This is part of a larger program; I'll explain only the relevant parts. Basically, my code wants to create a new connection to a remote host. This should return a Deferred, which fires once the connection is established, so I can send something on it.
I'm creating the connection with twisted.internet.interfaces.IReactorSSL.connectSSL
. That calls buildProtocol
on my ClientFactory
instance to get a new connection (twisted.internet.protocol.Protocol
) object, and returns a twisted.internet.interfaces.IConnector
. When the connection is started, Twisted calls startedConnecting
on the factory, giving it the IConnector
. When the connection is actually made, the protocol's connectionMade
callback is called, with no arguments.
Now, if I only needed one connection per host/port, the rest would be easy. Before calling connectSSL
, I would create a Deferred and put it in a dictionary keyed on (host, port). Then, in the protocol's connectionMade, I could use self.transport.getPeer()
to retrieve the host/port, use it to look up the Deferred, and fire its callbacks. But this obviously breaks down if I want to create more than one connection.
The problem is that I can't see any other way to associate a Deferred I created before calling connectSSL
with the connectionMade
later on.
Looking at this some more, I think I've come up with a solution, although hopefully there is a better way; this seems kind of weird.
Twisted has a class, ClientCreator
that is used for producing simple single-use connections. It in theory does what I want; connects and returns a Deferred
that fires when the connection is established. I didn't think I could use this, though, since I'd lose the ability to pass arguments to the protocol constructor, and therefore have no way to share state between connections.
However, I just realized that the ClientFactory
constructor does accept *args
to pass to the protocol constructor. Or at least it looks like it; there is virtually no documentation for this. In that case, I can give it a reference to my factory (or whatever else, if the factory is no longer necessary). And I get back the Deferred
that fires when the connection is established.