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

如何在Twisted的Protocol方法中修改Controller类的nodes变量?

解决Twisted中Protocol访问Controller实例的问题

嘿,我懂你现在的困扰——想把客户端IP加到Controller的nodes列表里,但在MyServerProtocol的connectionMade方法里死活拿不到Controller的引用对吧?这是因为你的Protocol和Controller之间还没建立关联,咱们一步步来搞定这个问题:

问题根源

你的MyServerProtocol实例是由ControllerFactory创建的,但Factory和Controller之间完全没有联系,所以Protocol自然找不到Controller的nodes列表。咱们需要把Controller的引用传递给Factory,再由Factory转交给Protocol。

修改步骤

  1. 把nodes改成Controller的实例变量
    先建议把nodes从类变量改成实例变量,这样每个Controller实例都有自己独立的节点列表,避免多个实例共享数据的意外问题:

    # controller.py
    class Controller(object):
        def __init__(self, port):
            self.nodes = []  # 改为实例变量,每个Controller拥有自己的节点列表
            ss = SimpleServer(port, self)  # 把Controller自身传给SimpleServer
    
  2. 让SimpleServer接收Controller的引用
    修改SimpleServer的初始化方法,让它把Controller的引用传给Factory:

    # server.py
    class SimpleServer():
        def __init__(self, port, controller):
            # 将controller实例传入ControllerFactory
            reactor.listenTCP(port, ControllerFactory(controller))
            print(f'server listening on {port}')
            reactor.run()
    
  3. 修改ControllerFactory,保存并传递Controller引用
    在Factory里存储Controller的引用,创建Protocol时把这个引用传递过去:

    # server.py
    class ControllerFactory(Factory):
        def __init__(self, controller):
            self.controller = controller  # 保存Controller的引用
    
        def buildProtocol(self, addr):
            proto = MyServerProtocol()
            proto.controller = self.controller  # 把Controller引用传给Protocol
            return proto
    
  4. 在connectionMade中操作Controller的nodes列表
    现在Protocol已经拿到了Controller的引用,就可以顺利添加客户端IP了:

    # server.py
    class MyServerProtocol(Protocol):
        def connectionMade(self):
            peer = self.transport.getPeer()
            # 把客户端IP(带端口)添加到nodes列表
            self.controller.nodes.append(f"{peer.host}:{peer.port}")
            print(f"Client {peer.host}:{peer.port} connected, added to nodes list")
    

这样修改之后,每次客户端连接时,它的IP地址就会被正确添加到Controller的nodes列表里了。

另外提一句,self.transport.getPeer()返回的是Twisted的IPv4Address/IPv6Address对象,如果你只需要纯IP字符串,直接用peer.host就可以啦。

内容的提问来源于stack exchange,提问作者Farah Zein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:59:14