You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Twisted基础TCP服务器中获取客户端列表并向所有客户端发数据?

嘿,这个需求其实挺常见的,Twisted 本身并没有提供现成的所有连接客户端列表,不过我们可以通过自定义 Factory 来自己维护这个列表,实现起来很简单:

具体实现步骤
  1. 自定义 Factory 类:继承 protocol.ServerFactory,在里面加一个集合来存储所有活跃的客户端连接实例
  2. 跟踪连接状态:在你的 Server Protocol 类里重写 connectionMade 和 connectionLost 方法,在客户端连接成功/断开时更新 Factory 里的客户端集合
  3. 实现广播函数:在 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:16:43