Question

I have been working on a P2P chat application based on kivy and twisted frameworks, I was hoping to get a lay of the land but I have run into this problem where if a client needs to connect to another client (via its server) it needs to perform a kind of handshake,

now the initial step was to connect to the client ;

conn = reactor.connectTCP(host, port, CommCoreClientFactory(self))

and then write into the connection;

conn.transport.write("data..\r\n")

Here the connection succeeds but the line doesn't go through, I have condensed the above code as per my intent, please see the method add_peer_to_swarm(self, pid, host) in comm/twisscomm.py

my clientProtocol/Factory and serverProtocol/Factory code can be found below; (they can be found in comm/commcoreclient.py and comm/commcoreserver.py resp.)

Client Protocol

class CommCoreClientProtocol(LineReceiver):

"""
Communications core client protocol code.
"""

def __init__(self, factory):

    self._peer_host = None
    self._peer_port = None
    self._peer_repr = None
    self.factory    = factory

def connectionMade(self):
    "Run when connection is established with server."

    self._peer_host = self.transport.getPeer().host
    self._peer_port = self.transport.getPeer().port
    self._peer_repr = self._peer_host + " on " + str(self._peer_port)

    Logger.debug(
        "Connection success! Connected to {}".format(self._peer_repr))

def connectionLost(self, reason):
    "Run when connection is lost with server."

    Logger.warn("Lost connection with peer {}".format(self._peer_repr))

def lineReceived(self, line):
    "Run when response is recieved from server."

    response = self.factory.app.handle_response(line)

    if response:
        print response

    Logger.debug("Recieved : {}".format(base64.b64encode(line)))

Client Factory

class CommCoreClientFactory(protocol.ReconnectingClientFactory):

protocol = CommCoreClientProtocol

def __init__(self, app):

    self.app = app

def startedConnecting(self, connector):
    "Run when initiaition of connection takes place."

    Logger.debug("Attempting connection...")

def buildProtocol(self, addr):
    "Build protocol on successful connection."

    Logger.debug("Connected.")
    Logger.debug("Resetting reconnection delay.")

    # Reset the delay on connection success
    self.resetDelay()

    # Overridden build protocol
    #client_protocol = self.protocol()
    #client_protocol.factory = self
    #return client_protocol

    return CommCoreClientProtocol(self)

def clientConnectionLost(self, connector, reason):
    "Run when connection with server is lost."

    #self.app.print_message("connection lost")
    Logger.debug("Lost connection: {}".format(reason.getErrorMessage()))

    return protocol.ReconnectingClientFactory.clientConnectionLost(
        self, connector, reason
    )

def clientConnectionFailed(self, connector, reason):
    "Run when attempt to connect with server fails."

    #self.app.print_message("connection failed")
    Logger.debug("Connection failed. {}".format(reason.getErrorMessage()))

    return protocol.ReconnectingClientFactory.clientConnectionFailed(
        self, connector, reason
    )

Server Protocol

class CommCoreServerProtocol(LineReceiver):

"Server backend to pocess the commands"

def __init__(self):

    self._peer_host = None
    self._peer_port = None
    self._peer_repr = None

def connectionMade(self):
    "Run when connection is established with server."

    self._peer_host = self.transport.getPeer().host
    self._peer_port = self.transport.getPeer().port
    self._peer_repr = self._peer_host + " on " + str(self._peer_port)

    Logger.debug(
        "Connection success! Connected to {}".format(self._peer_repr))

def connectionLost(self, reason):
    "Run when connection is lost with server."

    Logger.error("Lost connection with peer {}".format(self._peer_repr))

def lineReceived(self, line):

    print "REVCD LINE!", line

    response = self.factory.app.handle_recieved_data(line)

    if response:
        #self.transport.write(response)
        self.sendLine(response)

Server Factory

class CommCoreServerFactory(protocol.Factory):

protocol = CommCoreServerProtocol

def __init__(self, app):

    self.app = app

(Pardon the shoddy indent!)

I would like to know where I may be going wrong. Also If you are interested I have filed this issue. If you go through my code (comm/twiscomm.py) you will see some things may not work completely on the server side especially with the handle_received_data() but this is never even called as the data is not received.

Was it helpful?

Solution

The client howto explains and demonstrates how to use Twisted's network client APIs.

The API documentation for reactor.connectTCP also tells you things about its return value - an IConnector - notably, an interface lacking any transport attribute.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top