2010-05-17 52 views
2

我希望两种不同的协议互相交互的场景如下:不同的协议如何与扭曲的海誓山盟互动

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

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

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

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

有没有一种优雅的方式?例如使用战斗或任何其他事情。

我只是新的扭曲,不知道很多关于延迟执行....

非常感谢您!

回答

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的列表,并建立一个新的连接来检索消息的逻辑的是从实际协议实现(这完全是在扭曲的)分开。几乎所有这里使用的API返回的延迟都允许事件被连接起来,但是应用程序需要。