[Twisted-Python] waiting for results from tcp

Jean-Paul Calderone exarkun at divmod.com
Thu Oct 16 14:02:01 EDT 2008


On Thu, 16 Oct 2008 10:47:59 -0700 (PDT), Nima Ghanavatian <nimag at rogers.com> wrote:
>Hi,
>
>I have a server which can handle multiple connections.  At any given time, I want to send out a ping to see who is still listening to this server.
>
>For this I scan through my list of ip's and send out a msg with
>
>     factory = ClientFactory()
>     factory.protocol = caller
>     factory.message = self.message
>     factory.alive = 0
>     reactor.connectTCP(self.ip, self.port, factory)
>
>and wait on the response.  This is done from within an application daemon, so no reactor.run() is required.

I'm not sure I understand.  You have a server, but you're making outgoing
connects from it to other servers.  This will tell you what other servers
are still listening.  Is that what "to see who is still listening to this
server" means?

>
>How can I send a message out and wait for the response before proceeding?  I tried using deferreds a bunch of different ways but I can't seem to get it going.
>Oh and I should clarify I want the response to be in the original stream, not in the thread created by connectTCP/dataReceived/etc...
>

There are only two or three APIs in Twisted which will run your code in a
thread other than the reactor thread.  None of the connection setup APIs
or the network event APIs do this.  However, I'm confused by your comparison
of "the original stream" to "the thread created ...".  These aren't really
comparable things.

When you set up a TCP connection with reactor.connectTCP, data received
via the resulting connection is passed to the dataReceived method of the
protocol instance returned by the factory's buildProtocol method.  If you
want the data, that's how you get it: implement dataReceived to handle it
in the manner you wish.  For example, you could create a Deferred which
fires with all the data received over a single connection after that
connection closes:

    from twisted.internet.protocol import Protocol, ClientFactory
    from twisted.internet.defer import Deferred
    from twisted.python.log import err

    class GatherOutput(Protocol):
        def connectionMade(self):
            self.output = []
        def dataReceived(self, data):
            self.output.append(data)
        def connectionLost(self, reason):
            self.factory.dataDeferred.callback(self.output)

    f = ClientFactory()
    f.dataDeferred = Deferred()
    f.protocol = GatherOutput
    reactor.connectTCP(host, port, f)
    def gotData(data):
        print 'Got data', data
    f.dataDeferred.addCallback(gotData)
    f.dataDeferred.addErrback(err)
    reactor.run()

Deferreds are the most common way for dealing with potentially long-running
(or long-waiting) operations in Twisted.

Jean-Paul




More information about the Twisted-Python mailing list