[Twisted-Python] Multiple client connections

Jean-Paul Calderone exarkun at divmod.com
Wed Sep 6 15:27:53 MDT 2006


On Wed, 6 Sep 2006 17:12:29 -0400, Stan Benrsteen <sbernste at mitre.org> wrote:
>All,
>
>I want to write a client that connects to a Twisted Server using pb.   I 
>want my client to make several connections. For example:
>
>from twisted.spread import pb
>from twisted.internet import defer
>
>from twisted.internet.tcp import Connector
>from twisted.internet import reactor
>PORT = 8992
>
>class ModelCalculator:
>     def __init__(self, host, port):
>         self.host = host
>         self.port = port
>
>     def add(self, a, b):
>         self.factory = pb.PBClientFactory()
>         deferred = self.factory.getRootObject()
>         deferred.addCallback(self.connected, a, b)
>         deferred.addErrback(self.failure)
>         reactor.run()
>         return self.result

Instead, use this definition of add:

    def add(self, a, b):
        self.factory = pb.PBClientFactory()
        deferred = self.factory.getRootObject()
        deferred.addCallback(self.connected, a, b)
        deferred.addErrback(self.failure)
        return deferred

>
>     def connected(self, perspective, a, b):
>         deferred = perspective.callRemote('calculate', a, b)
>         deferred.addCallback(self.success, perspective)
>         deferred.addErrback(self.failure)

And this definition of connected:

    def connected(self, perspective, a, b):
        return perspective.callRemote('calculate', a, b)

>
>     def success(self, result, perspective):
>         self.result = result
>         self.stopReactor()
>
>     def failure(self, reason):
>         self.result = None
>         self.stopReactor()
>
>     def stopReactor(self):
>         reactor.stop()
>

Now you don't need any of these methods.

>if __name__ == '__main__':
>     calculator = ModelCalculator("127.0.0.1", PORT)
>     print calculator.add(4,5)
>     print calculator.add(14,5)
>     print calculator.add(24,5)
>     print calculator.add(34,5)
>

Rewrite this as:

    def reportSums(sums):
        for s in sums:
            print s

    def reportFailure(err):
        err.printTraceback()

    if __name__ == '__main__':
        calls = []
        calculator = ModelCalculator("127.0.0.1", PORT)
        for sums in [(4, 5), (14, 5), (24, 5), (34, 5)]:
            calls.append(calculator.add(*sums))
        d = defer.gatherResults(sums)
        d.addCallbacks(reportSumsm, reportFailure)
        d.addCallback(lambda ignored: reactor.stop())
        reactor.run()

>
>
>As you see, I want to add many numbers and print out the result.   This 
>doesn't work because the reactor is been stopped in the  stopReactor() 
>method that is invoked in either success() or failure ().  How can I change 
>it so I can call my remote add() method many  times without waiting for the 
>reactor to be stopped? Is there a way  that I can use the PB stuff without 
>the reactor?

Deferreds are the abstraction Twisted provides for dealing with callbacks.
It provides this abstraction because Twisted applications use callbacks
/a lot/.  You won't be able to avoid using them.  You need to structure
your programs in the way I have demonstrated above.

Jean-Paul




More information about the Twisted-Python mailing list