ActiveState Code

Recipe 181905: Network Ping Pong using Twisted Prespective Broker


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.

Python
 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()

Discussion

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.

Sign in to comment