如何在Twisted基础TCP服务器中获取客户端列表并向所有客户端发数据?
嘿,这个需求其实挺常见的,Twisted 本身并没有提供现成的所有连接客户端列表,不过我们可以通过自定义 Factory 来自己维护这个列表,实现起来很简单:
具体实现步骤
- 自定义 Factory 类:继承
protocol.ServerFactory,在里面加一个集合来存储所有活跃的客户端连接实例 - 跟踪连接状态:在你的
ServerProtocol 类里重写connectionMade和connectionLost方法,在客户端连接成功/断开时更新 Factory 里的客户端集合 - 实现广播函数:在 Factory 里写一个方法,遍历集合里的客户端,逐个发送数据
完整代码示例
from twisted.internet import protocol, reactor from twisted.internet.task import LoopingCall class Server(protocol.Protocol): def connectionMade(self): # 客户端连接成功时,把自己加入Factory的客户端集合 self.factory.clients.add(self) print(f"新客户端连接: {self.transport.getPeer()}") def connectionLost(self, reason): # 客户端断开时,从集合里移除自己 self.factory.clients.remove(self) print(f"客户端断开连接: {self.transport.getPeer()}") def dataReceived(self, data): print(f"收到数据: {data}") self.transport.write(data) class BroadcastServerFactory(protocol.ServerFactory): protocol = Server def __init__(self): # 用集合存储客户端,增删效率比列表高,还能自动去重 self.clients = set() def broadcast_to_all(self, message): # 遍历所有客户端发送消息,加异常捕获避免单个客户端影响全局 for client in self.clients: try: client.transport.write(message) except Exception as e: print(f"发送给客户端失败: {e}") # 初始化工厂和服务 factory = BroadcastServerFactory() reactor.listenTCP(8000, factory) # 举个例子:每5秒给所有客户端发一条测试消息 def send_test_broadcast(): factory.broadcast_to_all(b"全体客户端注意!这是一条广播消息\n") LoopingCall(send_test_broadcast).start(5) reactor.run()
关键点说明
- 用
set而不是列表来存客户端:因为客户端的连接/断开是高频操作,集合的增删操作效率更高,而且不会出现重复实例 - 一定要在
connectionLost里移除客户端:否则广播时会尝试向已经断开的连接发数据,引发不必要的异常 - 广播方法里加异常捕获:避免某个客户端的连接异常导致整个广播流程中断
内容的提问来源于stack exchange,提问作者DoubleFelix
相关产品推荐
相关产品推荐

