Skip to main content
 首页 » 编程设计

python之使用 Twisted, 'connectionMade' 如何触发特定的 Deferred

2025年05月04日8Leo_wl

这是一个更大计划的一部分;我只会解释相关部分。基本上,我的代码想要创建一个到远程主机的新连接。这应该返回一个 Deferred,一旦建立连接就会触发,这样我就可以在上面发送一些东西。

我正在使用 twisted.internet.interfaces.IReactorSSL.connectSSL 创建连接。在我的 ClientFactory 实例上调用 buildProtocol 以获取新连接 (twisted.internet.protocol.Protocol) 对象,并返回一个 twisted.internet.interfaces.IConnector.当连接开始时,Twisted 调用工厂的startedConnecting,给它IConnector。当实际建立连接时,将调用协议(protocol)的 connectionMade 回调,不带任何参数。

现在,如果每个主机/端口只需要一个连接,剩下的就很容易了。在调用 connectSSL 之前,我会创建一个 Deferred 并将其放入以 (host, port) 为键的字典中。然后,在协议(protocol)的 connectionMade 中,我可以使用 self.transport.getPeer() 检索主机/端口,使用它来查找 Deferred,并触发其回调。但如果我想创建多个连接,这显然会失败。

问题是我看不到任何其他方法可以将我在调用 connectSSL 之前创建的 Deferred 与稍后的 connectionMade 相关联。

请您参考如下方法:

再看看这个,我想我已经想出了一个解决方案,尽管希望有更好的方法;这看起来有点奇怪。

Twisted 有一个类,ClientCreator,用于生成简单的一次性连接。从理论上讲,它可以满足我的要求;连接并返回一个 Deferred,它在连接建立时触发。不过,我不认为我可以使用它,因为我失去了将参数传递给协议(protocol)构造函数的能力,因此无法在连接之间共享状态。

但是,我刚刚意识到 ClientFactory 构造函数确实接受 *args 传递给协议(protocol)构造函数。或者至少看起来像;几乎没有这方面的文档。在那种情况下,我可以给它一个对我工厂的引用(或者其他任何东西,如果工厂不再需要的话)。我取回了建立连接时触发的 Deferred。