On Wed, Oct 31, 2012 at 4:49 AM, Phil Mayers <p.may...@imperial.ac.uk> wrote: > 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. >
See also: http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#HowdoImakeinputononeconnectionresultinoutputonanother That example only uses a single connection in place of your clients A/B/C, but should be adaptable to your situation. -- Kevin Horn _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python