如何通过工厂以扭曲协议发送数据

我正在写一个实现自定义协议的客户端,并且有一个工厂。 我的问题如下:我的客户端有双向通信,有时我想告诉它“发送这些数据”。 但我拥有的是工厂对象:

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)

所以我创建了一个工厂并拥有一个工厂对象,我不是协议对象。 当send_message上面的send_message ,我得到一个错误,因为self.protocol只是一个类,而不是一个对象。

我怎样才能做到这一点? 除了工厂之外,我是否还应该公开连接协议?

谢谢


您可以访问所有您想要的对象。 工厂负责创建协议实例,因此如果您想将协议实例保留在工厂可以使用的地方,请覆盖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是事件驱动的,因此您需要确保通过响应表示连接已建立的事件来使用此代码。

您可以通过在构建协议时发起回调而不是仅设置属性来实现此目的。 扭曲实际上有一个助手工厂,它已经做了这样的事情:

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)

您还可以将对connectedProtocol的引用保存在cbConnected回调中,以便稍后继续使用它。 您也可以启动其他任何想要使用cbConnected的连接协议的cbConnected ,以便它们在实际可用之前不尝试使用连接。

链接地址: http://www.djcxy.com/p/29201.html

上一篇: how to send data with twisted protocol via factory

下一篇: restore objects location to default, after change to normal windows state