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

Gabriel Rossetti mailing_lists at evotex.ch
Thu Feb 21 11:05:32 EST 2008


Gabriel Rossetti wrote:
> 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
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
>
Sorry, I made a mistake, that should be :


   class MyXmlStreamFactory(xmlstream.XmlStreamFactory):

       protocol = XmlStreamTestSrv

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

           return p

but I get this error :

    File "test.py", line 91, in buildProtocol
    
xmlstream.XmlStreamFactory.addBootstrap(xmlstream.STREAM_START_EVENT, 
p._connected)
    exceptions.AttributeError: XmlStream instance has no attribute 
'_connected'

isn't p supposed to be a XmlStreamTestSrv? Why does it say it's a XmlStream?

Gabriel




More information about the Twisted-Python mailing list