Twisted - как создать многопротокольный процесс и отправлять данные между протоколами

Я пытаюсь написать программу, которая будет прослушивать данные (простые текстовые сообщения) на каком-то порту (скажем, tcp 6666), а затем передавать их одному или нескольким различным протоколам - irc, xmpp и так далее. Я перепробовал много подходов и покопался в Интернете, но не могу найти легкого и рабочего решения для такой задачи.

Код, с которым я сейчас борюсь, находится здесь: http://pastebin.com/ri7caXih

Я хотел бы знать, как от объекта вроде:

ircf = ircFactory ('asdfasdf', '# asdf666')

получить доступ к методам собственного протокола, потому что это:

self.protocol.dupa1 (сообщение)

возвращает ошибку о том, что self не передается активному объекту протокола. Или, может быть, есть другой, лучший, более простой и кошерный способ создать один реактор с несколькими протоколами и иметь триггеры действий, когда сообщение приходит на любой из них, а затем передавать это сообщение другим протоколам для обработки / обработки / отправки?

Любая помощь будет принята с благодарностью!


person SpankMe    schedule 26.03.2010    source источник


Ответы (3)


Вот пример кода для чтения из нескольких подключений к порту 9001 и записи в подключение через порт 9000. Вам потребуется несколько реализаций «PutLine», одна для XMPP, IRC, MSN и т. Д.

Я использовал глобал для хранения выходного соединения PutLine, но вы хотели бы создать более сложный объект Factory, который бы справился с этим.

#!/usr/bin/env python

from twisted.internet.protocol import Protocol, Factory
from twisted.internet.endpoints import clientFromString, serverFromString
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor

queue = []
putter = None

class GetLine(LineReceiver):
    delimiter = '\n'

    def lineReceived(self, line):
        queue.append(line)
        putter.have_data()
        self.sendLine(line)

class PutLine(LineReceiver):
    def __init__(self):
        global putter
        putter = self
        print 'putline init called %s' % str(self)

    def have_data(self):
        line = queue.pop()
        self.sendLine(line)


def main():
    f = Factory()
    f.protocol = PutLine
    endpoint = clientFromString(reactor, "tcp:host=localhost:port=9000")
    endpoint.connect(f)
    f = Factory()
    f.protocol = GetLine
    endpoint2 = serverFromString(reactor, "tcp:port=9001")
    endpoint2.listen(f)
    reactor.run()

if __name__ == '__main__':
    main()

Тестирование:

nc -l  9000
python test.py
nc 9001

Данные, введенные из любого числа nc 9001 (или netcat 9001), появятся на nc -l 9000.

person Rob Osborne    schedule 03.05.2011


См. doc/core/examples/chatserver.py. Там они добавили хуки к методам Protocol connectionMade и connectionLost для поддержки списка подключенных клиентов, а затем он перебирает их всех, когда приходит сообщение для передачи.

person keturn    schedule 26.03.2010
comment
Я думаю, это не решает мою проблему - этот пример отправляет сообщение каждому подключенному клиенту в диапазоне одного протокола. То, что я пытаюсь сделать, - это получить текстовую строку на некотором порту, а затем передать ее двум или более различным протоколам, где она может быть обработана в соответствии с методами, определенными протоколами, при получении сообщения - например, вставка полученной строки в канал irc , отправка через xmpp клиентам jabber и т. д. - person SpankMe; 26.03.2010
comment
Таким образом, вам нужно будет сделать то, что делает пример, с точки зрения отслеживания подключенных клиентов (по каждому протоколу), но также добавить некоторый объект более высокого уровня, который отслеживает все это. Это может быть созданный вами Service, который содержит ссылку на ваши irc и nagios фабрики и передает им сообщения. - person keturn; 26.03.2010
comment
Ну, кажется, я недостаточно просто объясняю проблему. Этот код нацелен на прослушивание порта 6666 и одновременный вход на irc (давайте пока отбросим jabber) в качестве бота, который будет отправлять сообщение, полученное на порту 6666, на канал irc, в который он будет входить. Это не проблема отправки сообщений между несколькими клиентами в одном протоколе, а передача данных между двумя (или более) независимыми протоколами / фабриками. Надеюсь, это поможет понять проблему, стоящую за кодом. - person SpankMe; 28.03.2010