【问题标题】:Twisted Python factory methods aren't getting called when using reactor wrappers使用反应器包装器时不会调用 Twisted Python 工厂方法
【发布时间】:2017-01-01 13:46:43
【问题描述】:

我有一个简单的客户端/服务器设置。这是客户端代码:

from twisted.internet import reactor
from twisted.internet import protocol
from twisted.internet.endpoints import TCP4ClientEndpoint

class MyProtocol(protocol.Protocol):

    def connectionMade(self):
        print "Hello!"

    def dataReceived(self, data):
        print data

class MyProtocolFactory(protocol.ClientFactory):

    def startedConnecting(self, connector):
        print "Starting to connect!"

    def buildProtocol(self, addr):
        return MyProtocol()

    def clientConnectionLost(self, connector, reason):
        print "Lost connection, reason = %s" % reason

    def clientConnectionFailed(self, connector, reason):
        print "Connection failed, reason = %s" % reason
        reactor.stop()

endpoint = TCP4ClientEndpoint(reactor, "127.0.0.1", 54321, timeout=5)
endpoint.connect(MyProtocolFactory())
reactor.run()

由于某种原因,此客户端将连接到服务器并且协议正常工作(我可以看到打印的“Hello!”以及服务器在成功连接时发送的数据),但它不会调用任何协议工厂方法。 startedConnecting 没有被调用,如果我停止服务器,我看不到 clientConnectionLost 被调用。如果我尝试在服务器启动之前运行客户端,我也希望看到 clientConnectionFailed 被调用。

这是奇怪的部分...如果我将上面代码中的最后 3 行更改为以下内容:

reactor.connectTCP("127.0.0.1", 54321, MyProtocolFactory())
reactor.run()

然后一切都按预期工作,并且在上述所有情况下都会调用所有方法。

我对端点的理解是,它们用附加行为包装了“connectTCP”(以及其他),但我不明白为什么它在第二个代码 sn-p 中有效,而不是在第一个代码中。

有什么想法吗?

【问题讨论】:

    标签: python python-2.7 twisted twisted.internet


    【解决方案1】:

    客户端端点接口不调用ClientFactory的额外连接状态通知方法。

    因此,虽然端点在某种意义上会“包装”connectTCP 等,但它们的行为与使用那些低级方法的行为并不完全相同。

    对于端点,工厂的工作是提供协议实例。工厂不再负责连接管理的其他方面。

    【讨论】:

    • 关于最后一句话,“使用端点 [...] 实例。工厂 [...] 管理。”从设计的角度来看,为什么工厂的行为会根据是否使用端点而改变?出于某种原因,这感觉非常不直观。如果不再是工厂的责任,那么使用端点时该功能从何而来?
    • 我记得,当时的想法是工厂界面不是很好,最好利用新的端点界面来帮助用户远离它。替换功能可能完全取决于您希望使用工厂方法实现的目标。 twistedmatrix.com/documents/16.4.1/api/… 涵盖了一些用例(大致是那些以前由 ReconnectingClientFactory 处理的用例)。
    • 感谢您的信息。您是否知道任何概述此替换功能和/或整体架构的文档? API 文档是一回事,但最好能总结一下这些东西应该如何使用和组合在一起。
    • 端点的散文/长格式/howto文档位于twistedmatrix.com/documents/current/core/howto/endpoints.html - afaik,这是最接近您要求的内容(尽管它可能会错过标记)。如果您认为它缺少一些重要的高级信息,我建议您提交一张票,描述您认为它没有回答的问题。
    • 我认为端点文档现在就足够了。也许这只是因为我对 twisted 还很陌生,并且学习了它所有的复杂性,但我认为如果有人制作一个带有块和箭头的高级系统架构图来显示一切是如何连接的,那将会非常棒。也许只是我的一厢情愿:-)。无论如何,感谢您的帮助和资源;这应该足以让我继续前进。
    【解决方案2】:

    补充我上面讨论的补充说明:

    如果您以前使用过 ClientFactory,请记住,connect 方法采用的是 Factory,而不是 ClientFactory。即使您将 ClientFactory 传递给 endpoint.connect,它的 clientConnectionFailed 和 clientConnectionLost 方法也不会被调用。特别是,扩展 ReconnectingClientFactory 的客户端不会重新连接。下一节将介绍如何在端点上设置重新连接客户端。

    来自此处找到的端点文档:http://twistedmatrix.com/documents/current/core/howto/endpoints.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多