【问题标题】:how to send data with twisted protocol via factory如何通过工厂使用扭曲协议发送数据
【发布时间】:2011-05-22 13:39:43
【问题描述】:

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

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 被调用时,我得到一个错误,因为self.protocol 只是一个类,而不是一个对象。

我该怎么做?除了工厂,我还应该公开连接协议吗?

谢谢

【问题讨论】:

  • 不能直接用构造函数来做对象吗?
  • @Dhaivat Pandya:我不明白
  • @Dhaivat Pandya:你不知道扭曲,我明白了。请不要回答

标签: python network-programming twisted


【解决方案1】:

您可以访问所有您想要的对象。工厂负责创建协议实例,因此如果您想将协议实例保留在工厂可以使用的地方,请覆盖 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 中启动任何其他想要使用连接协议的操作,这样他们就不会在连接实际可用之前尝试使用它。

【讨论】:

  • 谢谢,但是文档说不要使用 ClientCreator 而是使用端点,对吧?
  • 端点更新更好,也更灵活一些。我认为 ClientCreator 会使答案更容易理解。 :) 我将添加一个基于端点的版本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 2012-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-10
相关资源
最近更新 更多