Search code examples
pythontcptwistedprotocols

Running a function periodically in twisted protocol


I am looking for a way to periodically send some data over all clients connected to a TCP port. I am looking at twisted python and I am aware of reactor.callLater. But how do I use it to send some data to all connected clients periodically ? The data sending logic is in Protocol class and it is instantiated by the reactor as needed. I don't know how to tie it from reactor to all protocol instances...


Solution

  • You would probably want to do this in the Factory for the connections. The Factory is not automatically notified of every time a connection is made and lost, so you can notify it from the Protocol.

    Here is a complete example of how to use twisted.internet.task.LoopingCall in conjunction with a customised basic Factory and Protocol to announce that '10 seconds has passed' to every connection every 10 seconds.

    from twisted.internet import reactor, protocol, task
    
    class MyProtocol(protocol.Protocol):
        def connectionMade(self):
            self.factory.clientConnectionMade(self)
        def connectionLost(self, reason):
            self.factory.clientConnectionLost(self)
    
    class MyFactory(protocol.Factory):
        protocol = MyProtocol
        def __init__(self):
            self.clients = []
            self.lc = task.LoopingCall(self.announce)
            self.lc.start(10)
    
        def announce(self):
            for client in self.clients:
                client.transport.write("10 seconds has passed\n")
    
        def clientConnectionMade(self, client):
            self.clients.append(client)
    
        def clientConnectionLost(self, client):
            self.clients.remove(client)
    
    myfactory = MyFactory()
    reactor.listenTCP(9000, myfactory)
    reactor.run()