[Twisted-Python] Create client in Server factory

Grégoire Leroy gregoire.leroy at retenodus.net
Tue Nov 6 07:50:19 EST 2012


Hi,

Thank you, I've choosen the second solution, it works perfectly :)

Regards,
Grégoire Leroy

Le Wednesday 31 October 2012 18:49:33, Phil Mayers a écrit :
> On 10/31/2012 07:14 AM, Grégoire Leroy wrote:
> > Hi,
> > 
> > I have a server who receive data from clients A/B/C (remote machines). I
> > want to use a client D (on the same machine than the server) to send
> > this data to another server (remote).
> > 
> > The difficulty is, I want to use the same client D connection for any
> > client. I don't want open an new connection each time.
> > 
> > First thing I would think is to create the connection in my server
> > factory, and use client's methods in my server protocol, for example
> > with [...]
> > 
> > class LocalProxyFactory(Factory):
> >          def __init__(self):
> >                  f = LocalProxyClientFactory()
> >                  reactor.connectTCP("retenodus.net", 4242, f)
> >                  reactor.run()
> 
> The "reactor.run" is just wrong - remove it.
> 
> You need to connect to a server, and share this connection amongst some
> protocols. But you can't control the order in which these connections
> complete, so A/B/C might connect before D is ready.
> 
> You've really got two choices - accept the connections from A/B/C but
> have your server protocol "wait" until D is ready - something like this:
> 
> from twisted.internet.protocol import ClientCreator
> 
> class Server(...):
>    def connectionMade(self):
>      if self.factory.connD is None:
>        self.factory.waitFor(self._ready)
>        self.transport.pauseProducing()
> 
>    def _ready(self):
>      self.transport.resumeProducing()
> 
> d_connect = ClientCreator(reactor, DProtocol)
> 
> class ServerFactory(...):
>    def __init__(self):
>      self.connD = None
>      self._wait = []
>      d_connect.connectTCP(Dhost, port).addCallback(self.dReady)
> 
>    def waitFor(self, _cb):
>      if self.connD:
>        _cb(self.connD)
>      else:
>        d = defer.Deferred()
>        d.addCallback(_cb)
>        self._wait.append(d)
> 
>    def dReady(self, proto):
>      self.connD = proto
>      cb = self._wait
>      self._wait = []
>      for c in cb:
>        c.callback(proto)
> 
> def main():
>    reactor.listenTCP(..., ServerFactory())
>    reactor.run()
> 
> ...or don't start listening until D has connected, like this:
> 
> class ServerFactory(...):
>    def __init__(self, dProto):
>      self.connD = dProto
> 
> def startListen(dProto):
>    reactor.listenTCP(..., ServerFactory(dProto))
> 
> def main():
>    d_connect.connectTCP(Dhost, port).addCallback(startListen)
>    reactor.run()
> 
> The latter is simpler, but which is appropriate depends on your needs.
> 
> Note that I've used ClientCreator to get a callback when the connection
> to D is ready - remember that doesn't happen immediately.
> 
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python





More information about the Twisted-Python mailing list