使用reactor包装器时,不会调用Twisted Python工厂方法

时间:2017-01-01 13:46:43

标签: python python-2.7 twisted twisted.internet

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

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!”打印,以及服务器在成功连接时发送的数据),但它不会调用任何协议工厂方法。 beginConnecting没有被调用,如果我停止服务器,我看不到调用clientConnectionLost。如果我在服务器启动之前尝试运行客户端,我也希望看到调用clientConnectionFailed。

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

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

然后一切都按预期工作,所有方法都会在上面列出的所有情况下被调用。

我对端点的理解是它们将“connectTCP”(以及其他)与其他行为包装在一起,但我无法弄清楚为什么它在第二个代码片段中工作,而不是第一个。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

客户端端点接口不会调用ClientFactory

的额外连接状态通知方法

因此,虽然端点在某种意义上“包裹”connectTCP等,但它们与使用这些较低级别的方法具有完全相同的行为并不正确。

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

答案 1 :(得分:0)

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

  

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

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