Previous topic

the client exits the notification mode to download the available random number

Next topic

Higher level API

This Page

The user code is contain in one functionΒΆ

There is no more need to derive a class and override a specific method to process a notification. It is only a matter of using the API in one function separated from the protocol class. It is a simplification that actually does not buy much, it a higher level function which gets called when the connection is established, with the protocol instance as argument.

from twisted.internet import reactor, protocol, defer
from twisted.protocols import basic

class Client(basic.LineReceiver):
    
    delimiter = '\n'
    forever = True

    # Twisted callback
    def lineReceived(self, data):
        self.d.callback(data)
        
    # Internal function
    def command(self, cmd):
        self.sendLine(cmd)
        self.d = defer.Deferred()
        return self.d
    
    # user API
    def random(self):
        def cbRandom(data):
            return int(data)
        return self.command("random?").addCallback(cbRandom)

    def classified(self):
        return self.command("classified?")

    def notifMode(self,state=True):
        if state==True:
            return self.command("_notif_")
        elif:
            return self.command("_stop_notif_")

@defer.inlineCallbacks
def gotConnection(conn):

    print int((yield conn.random()))
    print (yield conn.classified()))        
    print (yield conn.notifMode()) 

    while True:
        notif = (yield conn.waitNotif())
        print "Hey, got a notif:", notif
        if notif=="classified":
            print "Oh an ad, not interested"
        elif notif=="random":
            print (yield conn.notifMode(False)) 
            print int((yield conn.random()))
            print (yield conn.notifMode()) 
        elif notif=="end":
            conn.forever = False
            
c = protocol.ClientCreator(reactor, Client)
c.connectTCP("localhost", 6789).addCallback(gotConnection)
reactor.run()

Here is the same script without API, where the protocole is exposed in raw form. This make it quite clear, what really is echanged on the wire, and what it happening with the protocol strings exchanged and the deferreds.

from twisted.internet import reactor, protocol, defer
from twisted.protocols import basic

class Client(basic.LineReceiver):
    
    def lineReceived(self, data):
        if data.startswith('notif: '):
            self.d_notif.callback(data)
        else:
            self.d.callback(data)
        
    def command(self, cmd):
        self.sendLine(cmd)
        self.d = defer.Deferred()
        return self.d
    
    def waitNotif(self):
        self.notif_d = defer.Deferred()
        return self.notif_d            

@defer.inlineCallbacks
def gotConnection(conn):

    print int((yield conn.command("random?")))
    print (yield conn.command("classified?"))        
    print (yield conn.command("_notif_")) 

    while True:
        notif = (yield conn.waitNotif())
        print "Hey, got a notif:", notif
        if notif=="classified":
            print "Oh an ad, not interested"
        elif notif=="random":
            conn.sendLine("stop_notif")
            print (yield conn.d)
            print int((yield conn.command("random?")))
            print (yield conn.command("notif")) 

c = protocol.ClientCreator(reactor, Client)
c.connectTCP("localhost", 6789).addCallback(gotConnection)
reactor.run()