[Twisted-Python] Create client in Server factory
![](https://secure.gravatar.com/avatar/284ca04c0e9b290f7f9a5c297c115942.jpg?s=120&d=mm&r=g)
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() [...] But in this case, code execution will stay in the reactor, right ? I have read that : http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#HowdoImakeinputo... But I don't know how it can be applied to my situation. Thanks, Grégoire Leroy
![](https://secure.gravatar.com/avatar/426d6dbf6554a9b3fca1fd04e6b75f38.jpg?s=120&d=mm&r=g)
On 10/31/2012 07:14 AM, Grégoire Leroy wrote:
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.
![](https://secure.gravatar.com/avatar/fcdfff68a2c9b2d1d199e4626998c791.jpg?s=120&d=mm&r=g)
On Wed, Oct 31, 2012 at 4:49 AM, Phil Mayers <p.mayers@imperial.ac.uk> wrote:
See also: http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#HowdoImakeinputo... That example only uses a single connection in place of your clients A/B/C, but should be adaptable to your situation. -- Kevin Horn
![](https://secure.gravatar.com/avatar/426d6dbf6554a9b3fca1fd04e6b75f38.jpg?s=120&d=mm&r=g)
On 10/31/2012 07:14 AM, Grégoire Leroy wrote:
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.
![](https://secure.gravatar.com/avatar/fcdfff68a2c9b2d1d199e4626998c791.jpg?s=120&d=mm&r=g)
On Wed, Oct 31, 2012 at 4:49 AM, Phil Mayers <p.mayers@imperial.ac.uk> wrote:
See also: http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#HowdoImakeinputo... That example only uses a single connection in place of your clients A/B/C, but should be adaptable to your situation. -- Kevin Horn
participants (3)
-
Grégoire Leroy
-
Kevin Horn
-
Phil Mayers