【问题标题】:How different protocols interact with eachother in TwistedTwisted 中不同的协议如何交互
【发布时间】:2010-05-17 09:41:22
【问题描述】:

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

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

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

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

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

有没有优雅的方法?例如使用 defered 或任何其他东西。

我刚接触twisted,不太了解defered....

非常感谢!

【问题讨论】:

    标签: python twisted protocols


    【解决方案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 允许按照您的应用程序的需要连接事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      • 2021-06-24
      • 2012-08-10
      • 2010-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多