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@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python