[Twisted-Python] Question about writing a server that accepts multiple clients with independent processing

Gabriel Rossetti mailing_lists at evotex.ch
Thu Feb 21 08:42:44 MST 2008


Phil Mayers wrote:
>>> You didn't by any chance use a class variable did you e.g.:
>>>
>>> class foo(...):
>>>   my_data = []
>>>   def dataReceived(self, data):
>>>     self.my_data.append(data)
>>>
>> Yes, that must be it :
>>
>>    class XmlStreamTestSrv(xmlstream.XmlStream):
>>
>>        def __init__(self):
>>            xmlstream.XmlStream.__init__(self)
>>            self.message = []
>
> No, this is fine, as you say setting "self.foo" creates an instance 
> variable.
>
> I personally don't use __init__ methods of the protocol because I 
> believe some protocols make complex use of this, but it should be fine.
>
>>    ...
>>
>> even though I though that in python if you put a "self." in front it 
>> was an instance variable and not a class variable. I have been also 
>> having some strange problems, like if I overload
>>
>>    def connectionMade(self):
>>
>> it never gets called, even though the parent class (XmlStream) also 
>> has it, and also I can't call self.transport.getPeer() or 
>> xmlstream.XmlStream.transport.getPeer(), I get :
>>
>>    print 'Connection from %s!' % 
>> str(xmlstream.XmlStream.transport.getPeer())
>>    exceptions.AttributeError: 'NoneType' object has no attribute 
>> 'getPeer'
>>
>> so maybe something is wrong somewhere.
>
> It sounds like the protocol isn't being hooked up to the transport.
>
>>> ...is wrong. "my_data" is shared by all instances of the class and 
>>> is mutable. You'll need to create instance variables, usually (I 
>>> believe) as part of the factory process.
>> Ok, I'll look into that, thanks.
>>>
>>> If you can write a minimal example showing the problem, someone can 
>>> probably tell you what you're doing wrong.
>>>
>> Ok, thanks, here's a minimal example :
>>
>>    from twisted.words.xish import xmlstream, domish
>>    from twisted.internet import reactor, protocol
>>    from twisted.internet.protocol import Protocol, Factory
>>    from twisted.words.xish import xpath
>>
>>
>>    class XmlStreamTestSrv(xmlstream.XmlStream):
>>
>>        def __init__(self):
>>            xmlstream.XmlStream.__init__(self)
>>            self.message = []
>>
>>        def connectionMade(self): # never called, why?
>>            print 'Connected :' #, string(self.transport.getPeer().host)
>>
>>        def _onHeader(self, element):
>>            #print "got header from % : %s" % 
>> (str(self.transport.getPeer().host), element.toXml())
>>            self.message.append(element.toXml())
>>
>>        def _connected(self, xs):
>>            #print 'Connection from %s!' % 
>> str(xmlstream.XmlStream.transport.getPeer().host)
>>            xs.addObserver("/header", self._onHeader)
>>
>>    if __name__ == "__main__":
>>
>>        c = XmlStreamTestSrv()
>>
>>        f = xmlstream.XmlStreamFactory()
>>        #f.addBootstrap(xmlstream.STREAM_CONNECTED_EVENT, c._connected)
>>        f.addBootstrap(xmlstream.STREAM_START_EVENT, c._connected)
>>
>>        reactor.listenTCP(4321, f)
>>        reactor.run()
>
> Ah - you need to set the "protocol" attribute on the factory to the 
> protocol *class*, and then when a connection is made the class will be 
> instantiated and connected to the transport. This is why 
> self.transport is None, and because you're using an instance of the 
> protocol, the data is getting squashed together. Do this:
>
> f = xmlstream.XmlStreamFactory()
> f.protocol = XmlStreamTestSrv
> reactor.listenTCP(4321, f)
> reactor.run()
>
Ahh, ok, I get it, and I should therefor subclass 
xmlstream.XmlStreamFactory and add the bootstrap there, something like :

    class MyXmlStreamFactory(xmlstream.XmlStreamFactory):

        protocol = XmlStreamTestSrv

        def buildProtocol(self, *pargs, **kwargs):
            p = xmlstream.XmlStreamFactory.buildProtocol(self, *pargs, 
**kwargs)
            addBootstrap(xmlstream.STREAM_START_EVENT, p._connected)

            return p

Regards,
Gabriel Rossetti




More information about the Twisted-Python mailing list