Search code examples
pythonreturnchattwisted

can I return data in python twisted's dataRecieved method


I Searched and think twisted's dataReceived method cannot return, so is there any way to return data so that I can call the dataReceived when I need data or is there any other technique to get data in other user define methods when needed ?


Solution

  • Hopefully I have correctly understood your question.

    Here's a hyper-simplified version of one way to get messages out of an active protocol dataReceived method. I've run it on one of our servers to make sure it works

    This example uses a queue that the protocol writes to and a thread reads from to transfer data.

    In this example, the showMessage function automatically prints received messages. You could do something else, like allow messages to accumulate in the queue and on command retrieve them from the queue in batches.

    Keep in mind that a production system would have to allow for mutliple messages in a single dataReceived message. In a production scenario you might also use some more thread-appropriate inter-process communication method. Having said that, I think that deque is thread safe and it seems to work the way I've shown. (more info on dequeue at PMOTW

    from __future__ import print_function
    from collections import deque
    import threading
    import time
    from twisted.internet import reactor
    from twisted.internet.protocol import Factory, Protocol
    
    class MsgReceiver(Protocol):
        def __init__(self, myQueue):
            self.myQueue = myQueue
    
        def connectionMade(self):
            print("Connection made!")
    
        def dataReceived(self, msg):
            self.myQueue.append(msg)
    
    class MsgReceiverFactory(Factory):
        def __init__(self, myQueue):
            self.myQueue = myQueue
    
        def buildProtocol(self, addr):
            return MsgReceiver(self.myQueue)
    
    def showMessages(myQueue):
        while True:
            time.sleep(1)
            try:
                msg = myQueue.popleft()
                print(msg)
            except IndexError:
                print("No messages in the queue")
    
    myQueue = deque()
    
    factory = MsgReceiverFactory(myQueue)
    p = threading.Thread(target=showMessages, args=(myQueue,))
    p.daemon = True
    p.start()
    
    reactor.listenTCP(42000, factory)
    reactor.run()