A simple program using Twisted Perspective Broker and showing use of Twisted Deferreds and other callback mechanisms. Start the server without arguments and the client with the host name of the server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | from twisted.spread import pb
from twisted.internet import reactor
import sys
PORT = 8992
DELAY = 1
DOG_DELAY = 2
RESTART_DELAY = 5
class Pinger:
def __init__( self, host ):
self.ping = None
self.host = host
self.ball = 0
self._start()
def _start( self ):
print 'Waiting for Server...'
dfr = pb.getObjectAt( self.host, PORT, 30 )
dfr.addCallbacks( self._gotRemote, self._remoteFail )
def _gotRemote( self, remote ):
remote.notifyOnDisconnect( self._remoteFail )
self.remote = remote
self._ping()
def _remoteFail( self, _ ):
if self.ping:
self.ping.cancel()
self.ping = None
self.restart = reactor.callLater( RESTART_DELAY, self._start )
def _ping( self ):
self.dog = reactor.callLater( DOG_DELAY, self._start )
self.ball += 1
print 'THROW', self.ball,
dfr = self.remote.callRemote( 'Pong', self.ball )
dfr.addCallbacks( self._pong, self._remoteFail )
def _pong( self, ball ):
self.dog.cancel()
print 'CATCH', ball
self.ball = ball
self.ping = reactor.callLater( DELAY, self._ping )
class Ponger( pb.Root ):
def remote_Pong( self, ball ):
print 'CATCH', ball,
ball += 1
print 'THROW', ball
return ball
if len( sys.argv ) > 1 :
Pinger( sys.argv[1] )
else:
reactor.listenTCP( PORT, pb.BrokerFactory( Ponger()))
reactor.run()
|
If the connection fails for any reason then the client should attempt to reconnect. If you kill the server then the client will wait for it to be restarted. Would be nice to have a graphical display that shows a ball being thrown from host to host.
I'm n00b to Twisted and trying to learn by reading everything I can get my eyes on. I felt that this recipe went a long way toward my "getting it" about pb, and I wish I had read this example a couple weeks ago.
I had to modify Pinger._start() as follows to get it to work on a recent Twisted since pb.getObjectAt() is no longer around:
Twisted version 13.2.0 requires the listenTCP to be modified a bit: reactor.listenTCP( PORT, pb.PBServerFactory( Ponger()))