Как разные протоколы взаимодействуют друг с другом в Twisted - PullRequest
2 голосов
/ 17 мая 2010

Сценарий, в котором я хочу, чтобы два разных протокола взаимодействовали друг с другом, приведен ниже:

A и B - это два разных протокола.Сначала А будет взаимодействовать с сервером и получать некоторые значения.Только после того, как А завершит получение значений, В начнет взаимодействовать с сервером.

Теперь моя проблема в том, что существует элегантный способ инициализации В, когда А получает значения.

В настоящее время ятолько начальный B в функции обработки данных А.Но я не думаю, что это элегантный способ.

То, что я имею в виду под элегантным способом, состоит в том, что инициализация B выполняется контроллером потока или чем-то в этом роде, но не другим протоколом.

Есть ли элегантный способ?например, используя defred или любые другие вещи.

Я просто новичок в закрученном, не очень много знаю о побежденном ....

Большое спасибо!

1 Ответ

1 голос
/ 17 мая 2010

Похоже, что вы преодолели первое препятствие - выяснить, как заставить А и В взаимодействовать на всех . Это хорошо, поскольку для большинства людей это самая большая концептуальная задача. Что касается того, чтобы сделать его элегантным , если вы придерживаетесь подхода, который изолирует ваш код протокола от кода приложения, управляющего им (т. Е. «Бизнес-логика»), есть несколько вариантов. Я приведу пример, основанный на отсрочке.

Давайте рассмотрим двух клиентов 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-интерфейсами, используемыми здесь, позволяют подключать события так, как того требует ваше приложение.

...