您可以访问所有您想要的对象。工厂负责创建协议实例,因此如果您想将协议实例保留在工厂可以使用的地方,请覆盖 buildProtocol 并保存该实例:
class MyFactory(ClientFactory):
protocol = MyProtocol
...
def buildProtocol(self, address):
proto = ClientFactory.buildProtocol(self, address)
self.connectedProtocol = proto
return proto
但是,这种方法缺少一个重要功能。很难判断何时调用了 buildProtocol 和设置了 connectedProtocol。如果您尝试天真地使用此属性:
factory = MyFactory()
reactor.connectTCP(host, port, factory)
factory.connectedProtocol.send_message(...)
代码将失败并显示AttributeError,因为尚未实际建立连接。由于 Twisted 是事件驱动的,因此您需要确保通过响应表明连接已建立的事件来使用此代码。
您可以通过在构建协议时触发回调来做到这一点,而不仅仅是设置属性。 Twisted 实际上有一个辅助工厂,它已经做了这样的事情:
from twisted.internet.protocol import ClientCreator
cc = ClientCreator(reactor, MyProtocol)
whenConnected = cc.connectTCP(host, port)
# Or the equivalent with endpoints
# from twisted.internet.endpoints import TCP4ClientEndpoint
# from twisted.internet.protocol import ClientFactory
# endpoint = TCP4ClientEndpoint(reactor, host, port)
# factory = ClientFactory()
# factory.protocol = MyProtocol
# whenConnected = endpoint.connect(factory)
def cbConnected(connectedProtocol):
connectedProtocol.send_message(...)
def ebConnectError(reason):
# Connection attempt failed, perhaps retry
...
whenConnected.addCallbacks(cbConnected, ebConnectError)
您还可以在cbConnected 回调中保存对connectedProtocol 的引用,以便以后继续使用它。您也可以在 cbConnected 中启动任何其他想要使用连接协议的操作,这样他们就不会在连接实际可用之前尝试使用它。