[Twisted-Python] How can I send unique configuration data for multiple connections through a factory?

Arjan Scherpenisse arjan at scherpenisse.net
Wed Feb 10 14:38:48 EST 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

If you create two instances of your ClusterClientFactory, each with a
unique string, you should be fine. Requires only a small modification:

         factory = ClusterClientFactory()
         factory.maxDelay = 120  #  two minutes
         factory.connectString = "FirstString..."
         reactor.connectTCP("localhost", 7300, factory)

         factory2 = ClusterClientFactory()
         factory2.maxDelay = 120  #  two minutes
         factory2.connectString = "SecondString"
         reactor2.connectTCP("localhost", 7300, factory)

You can clean this up by putting the maxDelay and connectString in the
constructor of the factory:

reactor2.connectTCP("localhost", 7300, ClusterClientFactory(120, "First"))
reactor2.connectTCP("localhost", 7300, ClusterClientFactory(120, "Second"))

Arjan

Mark Bailey wrote:
> Good day:
> 
> I've been having fun with Twisted.  I have my application running fine,
> with multiple server and client connections using Telnet.  :-)
> 
> However, users always want something.  I need to send some unique
> configuration information to each connection.  The connections are made
> using connectTCP.  My first attempt assumed that the connection was made
> when the call to connectTCP was executed.  It didn't work!  :-(
> 
> -------------------------------
> 
> from twisted.internet.protocol import ClientFactory
> from twisted.internet import reactor
> from twisted.conch.telnet import StatefulTelnetProtocol
> 
> class testClient(StatefulTelnetProtocol):
> 
>     def connectionMade(self):
>         self.title = self.factory.connectString
>         print "Client Connected: " + self.title
>         self.setRawMode()
>         self.factory.connections.append(self)
> 
>     def connectionLost(self, reason):
>         if self in self.factory.connections:
>             self.factory.connections.remove(self)
> 
>     def rawDataReceived(self,data):
>         print data + "\n"
> 
> class ClusterClientFactory(ClientFactory):
> 
>     protocol = testClient
> 
>     def __init__(self):
>         self.connections = []
>         self.connectString = ''
> 
>     def startFactory(self):
>         print "startFactory: " + self.connectString
> 
>     def startedConnecting(self, connector):
>         print "Started connecting: " + str(connector)
>         print self.connectString
> 
>     def buildProtocol(self, addr):
>         print "bulldProtocol: " + str(addr)
>         print "buildProtocol: " + self.connectString
> 
>         p = self.protocol()
>         p.factory = self
>         return p
> 
> if __name__ == '__main__':
> 
> 
>     def startUp():
> 
>         factory = ClusterClientFactory()
>         factory.maxDelay = 120  #  two minutes
> 
>         factory.connectString = "FirstString..."
>         reactor.connectTCP("localhost", 7300, factory)
> 
>         factory.connectString = "SecondString"
>         reactor.connectTCP("localhost", 7300, factory)
> 
>     reactor.callWhenRunning(startUp)
>     reactor.run()
> 
> ----------------------------------
> 
> The results are that buildProtocol gets the second string both times. 
> startedConnecting gets the correct string, but all I have there is a
> connection object.  I need the correct data in buildProtocol to do it
> this way.
> 
> ------------------------------------
> 
> C:\Users\Mark\src\play>python testclient.py
> startFactory: FirstString...
> Started connecting: <twisted.internet.tcp.Connector instance at 0x01DAB620>
> FirstString...
> Started connecting: <twisted.internet.tcp.Connector instance at 0x01E0EFD0>
> SecondString
> bulldProtocol: IPv4Address(TCP, '127.0.0.1', 7300)
> buildProtocol: SecondString
> Client Connected: SecondString
> Welcome to SimpleServer5
> 
> 
> 
> bulldProtocol: IPv4Address(TCP, '127.0.0.1', 7300)
> buildProtocol: SecondString
> Client Connected: SecondString
> Welcome to SimpleServer5
> 
> --------------------------
> 
> 
> My "best" idea is to pass the strings to the factory in a dictionary
> indexed by the IP address and the port.  Then, buildProtocol() can use
> that to recover the string and I can use reactor.resolve() to translate
> the host name to the IP address.  The real application won't have
> multiple connections to the same host and port like this example, so
> this would work.
> 
> There MUST be a better way.  :-)
> 
> My "simpleserver" is below if you want to run this.
> 
> THANKS for all of your help.  I have the basic application running now
> (including a Tkinter GUI  :-) ) and Twisted has saved me hundreds or
> even thousands of lines of code...
> 
> Mark Bailey
> 
> ------------------------------
> 
> from twisted.conch.telnet import StatefulTelnetProtocol
> from twisted.internet import reactor, protocol
> from twisted.protocols.basic import LineReceiver
> 
> class TelnetEcho(StatefulTelnetProtocol):
>     def connectionMade(self):
>         self.factory.connection.append(self)
>         self.sendLine("Welcome to SimpleServer5\r\n")
> 
> 
>     def lineReceived(self, data):
>         data = data.rstrip('\n\r')
> 
>         if data.upper() == 'BYE':
>             self.sendLine("Goodbye...\r")
>             self.transport.loseConnection()
>         else:
>             self.sendLine("Unrecognized command: %r\r" % (data,))
> 
>     def connectionLost(self, reason):
>         self.factory.connection.remove(self)
> 
> 
> class TelnetEchoFactory(protocol.Factory):
>     protocol = TelnetEcho
>     def __init__(self):
>         self.connection = []
> 
> 
> def createTelnetServer(port=7300):
>     telnetinstance = TelnetEchoFactory()       #  needs to be a list
>     reactor.listenTCP(port,telnetinstance)
> 
> if __name__ == "__main__":
>     reactor.callWhenRunning(createTelnetServer)
>     reactor.run()
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAktzC0MACgkQigE4AbflYer9nwCgixra0FaTD6ubvGJufjApRG/m
A34An3C2ng+4x3/halWSgGQUvQvsCiTM
=Cg6W
-----END PGP SIGNATURE-----



More information about the Twisted-Python mailing list