[Twisted-Python] Transfering a transport between DatagramProtocols

Olivier Parisy olivier.parisy at free.fr
Sat Nov 28 15:52:55 MST 2009


Glyph Lefkowitz a écrit :
> On Nov 24, 2009, at 4:26 PM, Olivier Parisy wrote:
>
>   
>> Is this the "twisted" way to analyse this? Or should I use some kind of 
>> "proxy" DatagramProtocol which would relay datagramReceived calls to the 
>> proper DatagramProtocol, depending on the current protocol state 
>> (handshaking or data exchange)?
>>     
>
> Currently, the right way to do this is to do as you suggest, and have two DatagramProtocol instances, and a third which switches between them.
>   
I tried to implement such a "switching" class so that I could freely 
change the DatagramProtocol handling a given port without releasing it.

It is typically used in the following way :
        self.protocol = 
DelegatingDatagramProtocol(MyFirstDatagramProtocol())
        self.udpPort = reactor.listenUDP(0, self.protocol)

Then, later in the code :
       self.protocol.switchProtocol(MySecondDatagramProtocol())

Here is my current implementation :

# Breaks when inheriting from DatagramProtocol?
class DelegatingDatagramProtocol:
    def __init__(self, protocol):
        self._protocol = protocol

    def switchProtocol(self, protocol):
        self._protocol = protocol
        protocol.transport = self.transport
       
    def makeConnection(self, transport):
        self._protocol.makeConnection(transport)
        # Needed by switchProtocol
        self.transport = transport
       
    # Avoid an AssertionError (protocol.py:527 assert self.numPorts > 0)
    def doStop(self):
        pass
   
    # See 
http://www.python.org/workshops/1997-10/proceedings/savikko.html (Proxy 
pattern)
    def __getattr__(self, name):
        print 'Delegating to protocol: %s' % name
        return getattr(self._protocol, name)

It mostly works, but I have two issues with it :
- When doStop() is called by the reactor, an AssertionError is raised. I 
suppose this is due to my "sharing" of the transport in switchProtocol 
(which ensures that "transport.write" calls are directed to the proper 
transport), but how can I fix it?
- If my class extends DatagramProtocol, it stops working 
(transport.write calls seems honored, then nothing works... I suppose 
datagramReceived is never called). Why is it so?

Regards,
Olivier.






More information about the Twisted-Python mailing list