在Twisted协议中定期运行函数

24 投票
2 回答
8232 浏览
提问于 2025-04-11 19:28

我想找一种方法,定期向所有连接到某个TCP端口的客户端发送一些数据。我在研究Twisted这个Python库,知道有个叫reactor.callLater的东西。但我不太清楚怎么用它定期向所有连接的客户端发送数据。发送数据的逻辑是在Protocol类里面的,而这个类是由reactor根据需要创建的。我不知道怎么把reactor和所有的Protocol实例连接起来……

2 个回答

3

我想最简单的方法就是在协议中管理一个客户端的列表,利用连接建立和连接断开的功能,然后用一个循环调用去让每个客户端发送数据。

这样做可能有点强迫,但我觉得如果没有协议对数据的发送和接收进行一些控制,你可能不太想这样做。当然,我需要看看你的代码,才能更好地理解它是如何适应的。你有GitHub链接吗? :)

38

你可能想在连接的工厂里处理这个问题。工厂并不会自动知道每次连接建立或断开,所以你可以通过协议来通知它。

下面是一个完整的例子,展示了如何使用 twisted.internet.task.LoopingCall 和自定义的基本工厂和协议,每10秒向每个连接发送一次“10秒过去了”的消息。

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()

撰写回答