zah*_*pov 7 python network-programming twisted
我正在编写一个实现自定义协议的客户端,并且有一个工厂.我的问题如下:我的客户端有双向通信,有时我想告诉它"发送此数据".但我所拥有的只是工厂对象:
class MyFactory(ClientFactory):
protocol = MyProtocol
def __init__(self, recv_callback):
self.recv_callback = recv_callback
def send_message(self, msg):
self.protocol.send_message(msg)
Run Code Online (Sandbox Code Playgroud)
所以我创建了一个工厂并拥有一个工厂对象,我没有协议对象.当send_message
调用上面时,我得到一个错误,因为self.protocol
它只是一个类,而不是一个对象.
我怎样才能做到这一点?除了工厂之外,我还应该公开连接协议吗?
谢谢
Jea*_*one 10
您可以访问所需的所有对象.工厂负责创建协议实例,因此如果您希望将协议实例保留在工厂可以使用的位置,请覆盖buildProtocol
并保存实例:
class MyFactory(ClientFactory):
protocol = MyProtocol
...
def buildProtocol(self, address):
proto = ClientFactory.buildProtocol(self, address)
self.connectedProtocol = proto
return proto
Run Code Online (Sandbox Code Playgroud)
但是,这种方法缺乏一个重要特征.它不容易判断何时buildProtocol
被调用并connectedProtocol
已设置.如果您尝试天真地使用此属性:
factory = MyFactory()
reactor.connectTCP(host, port, factory)
factory.connectedProtocol.send_message(...)
Run Code Online (Sandbox Code Playgroud)
代码将失败,AttributeError
因为尚未实际建立连接.由于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)
Run Code Online (Sandbox Code Playgroud)
您还可以将引用保存connectedProtocol
在cbConnected
回调中,以便以后继续使用它.您也可以启动其他任何想要使用连接协议的操作cbConnected
,这样他们就不会在实际可用之前尝试使用连接.
归档时间: |
|
查看次数: |
5661 次 |
最近记录: |