我希望两种不同协议相互作用的场景如下:
A和B是两种不同的协议。 First A将与服务器交互并检索一些值。 只有在A完成检索值后,B才会开始与服务器进行交互。
现在我的问题是当A检索值时,有一种优雅的方式来初始化B.
目前我只是在A的数据处理功能中初始化B.但我不认为这是一种优雅的方式。
我的意思是优雅的方式是B的初始化是由流量控制器或类似的东西完成的,而不是另一种协议。
有优雅的方式吗?使用deferred或任何其他东西。
我只是吵得一团糟,不太了解被推迟......
非常感谢!
答案 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允许事件连接,但是您的应用程序需要。