[Twisted-Python] Distinguishing TCP connections

Grant McDonald gmcdonald at infocomp.com
Tue Jun 21 19:15:51 MDT 2005


Eric,

I came up with a nice way of managing connections on the last project I
worked on:

The DataConnection is the protocol instance (in this case inheriting from
Int32StringReceiver).  Each time a protocol connects it calls the
registerSource

class DataConnection(Int32StringReceiver):
    
    def __init__(self, manager):
        self.manager = manager
    
    def closeConnection(self):
        self.transport.loseConnection()
    
    def connectionMade(self):
        print 'registering connection'
        self.registerConnection()
        
    def connectionLost(self, reason):
        print 'connection lost, removing....'
        self.removeConnection()

	.
	.
[ code omitted for brevity ]
	.
	.
 
    def registerConnection(self):
        """
        register data connection with connection manager.
        """
        self.manager.registerSource(self)
        
    def removeConnection(self):
        """
        remove this connection from the connection manager.
        """
        self.manager.removeSource(self.id)

    def setId(self, id):
        self.id = id
        
And the ConnectionManager is the factory class (inherited from the generic
Factory class).
 
class ConnectionManager(Factory):
    
    def __init__(self, eventhandler):
        self.ids = 0
        self.sources = {}
        self.eventhandler = eventhandler    # -- see comments later
    
    def buildProtocol(self, addr):
        return DataConnection(self)

    def newId(self):
        """
        get an id that is unique for the life of the connection manager.
        """
        id = self.ids+1
        self.ids = id
        return id

    def registerSource(self, source):
        """
        register a new source, this assigns the source an id and
        adds it to the sources dictionary.
        """
        id = self.newId()
        self.sources[id] = source
        
        # set source id
        source.setId(id)

    def removeSource(self, id):
        """
        remove the connection indicated by the source id from the current
connection
        pool any subsequent behaviour must be handled in the event manager.
        """
        if self.sources.has_key(id):
            del self.sources[id]

    def closeConnections(self):
        for source in self.sources.values():
            source.closeConnection()

[ code omitted for brevity ]

As you can see the when a connection is made it is registered with the
factory instance.  This uniquely identifies the connection, and allows you
to identify when you get a message which connection it is from.  This also
simplifies sending a message back along the same channel:

To do this you can create an event handler that implements some form of
event processing:

class EventHandler:

    def __init__(self, manager):
        self.manager = manager

    def messageReceived(self, id, message):
        # process message
        ...
        
        # create new message
        newMessage = "this is a test"
        
        # send new message back along same connection
        self.manager.sendMessage(id, newMessage)

And in the ConnectionManager add something like the following methods:

    def propagateMessage(self, id, message):
        """
        This method simply passes the received message through to the
        EventHandler class instance along with the id of the connection
        the message was received from.
        """
        self.eventhandler.messageReceived(id, message)
        
    def sendMessage(self, id, message):
        """
        This method retrieves the correct connection and sends a message
through it.
        """
        if self.sources.has_key(id):
            self.sources[id].emitMessage(message)

And the DataConnection:

    def stringReceived(self, data):
        self.manager.propagateEvent(self.id, data)

    def emitMessage(self, message):
        """
        send a message along the data connection.
        """
        self.sendString(message)


If any of this is unclear please let me know.

Regards,

Grant McDonald

----Original Message-----
From: twisted-python-bounces at twistedmatrix.com
[mailto:twisted-python-bounces at twistedmatrix.com]On Behalf Of Eric Hsu
Sent: 21 June 2005 17:33
To: radix at twistedmatrix.com
Cc: Twisted general discussion
Subject: Re: [Twisted-Python] How could I distinguish each TCP connection?

Thank you very much!
You've been a GREAT help :D
2005/6/21, Christopher Armstrong <radeex at gmail.com>:
I suggest, instead of using the stock "Factory", making a subclass of
it with buildProtocol implemented like so:

def buildProtocol(self, addr):
    p = Factory.buildProtocol(self, addr)
    self.connections.append (p)
    return p

Or similar (you'll have to define the 'connections' list yourself in
__init__). In the protocol's connectionLost, you could then remove the
protocol from that list.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/twisted-python/attachments/20050622/31e3f5a4/attachment.html>


More information about the Twisted-Python mailing list