Twisted中不同协议如何相互交互

时间:2010-05-17 09:41:23

标签: python twisted protocols

我希望两种不同协议相互作用的场景如下:

A和B是两种不同的协议。 First A将与服务器交互并检索一些值。 只有在A完成检索值后,B才会开始与服务器进行交互。

现在我的问题是当A检索值时,有一种优雅的方式来初始化B.

目前我只是在A的数据处理功能中初始化B.但我不认为这是一种优雅的方式。

我的意思是优雅的方式是B的初始化是由流量控制器或类似的东西完成的,而不是另一种协议。

有优雅的方式吗?使用deferred或任何其他东西。

我只是吵得一团糟,不太了解被推迟......

非常感谢!

1 个答案:

答案 0 :(得分:1)

听起来你已经超越了第一道障碍 - 弄清楚如何让A和B完全互动。这很好,因为对大多数人来说这是最大的概念挑战。至于使它优雅,如果您采用的方法使您的协议代码与驱动它的应用程序代码(即“业务逻辑”)隔离,则有几种选择。我将举一个基于Deferreds的例子。

让我们考虑两个POP3客户端。您希望第一个检索消息列表,然后第二个从结果列表中检索第一个消息。这个例子

from twisted.internet import defer, protocol, reactor
from twisted.mail.pop3 import AdvancedPOP3Client

class MessageDownloader(object):
    def __init__(self, host, port, user, password):
        self.host = host
        self.port = port
        self.user = user
        self.password = password
        self.cc = ClientCreator(reactor, AdvancedPOP3Client)


    def connect(self):
        """
        Connect to the POP3 server and authenticate.  Return a Deferred
        which fires with the connected protocol instance.
        """
        connDeferred = self.cc.connect(self.host, self.port)
        def cbAuthenticate(proto):
            loginDeferred = proto.login(user, password)
            loginDeferred.addCallback(lambda ignored: proto)
            return loginDeferred
        connDeferred.addCallback(cbAuthenticate)
        return connDeferred


    def run(self):
        connDeferred = self.connect()
        connDeferred.addCallback(self.cbFirstConnection)
        return connDeferred


    def cbFirstConnection(self, firstProto):
        listDeferred = firstProto.listUID()

        def cbListed(uidList):
            connDeferred = self.connect()
            def cbConnected(secondProto):
                return secondProto.retrieve(uidList[0])
            connDeferred.addCallback(cbConnected)
        listDeferred.addCallback(cbListed)
        return listDeferred

if __name__ == '__main__':
    import sys
    MessageDownloader(*sys.argv[1:]).run()
    reactor.run()

这里,关于检索UID列表和设置新连接以检索消息的所有逻辑都与实际协议实现(完全是Twisted)分开。从这里使用的几乎所有API返回的Deferreds允许事件连接,但是您的应用程序需要。