Отправка данных, полученных на одной фабрике Twisted, на другую фабрику - PullRequest
5 голосов
/ 17 сентября 2010

Я пытаюсь написать простую программу, используя Twisted Framework, и я пытаюсь решить (или даже представить, как ее написать) проблему, я не могу найти какую-либо соответствующую документацию для:

Основной реактор использует две фабрики, одну настраиваемую, прослушивающую TCP-соединения для данного порта (скажем, 8000) и вторую, для входа на данный IRC-сервер и канал. Получив данные (простой, однострочный текст) на заводском прослушивании в 8000, мне нужно передать эти данные на вторую фабрику, чтобы затем их можно было соответствующим образом обработать - либо отправить сообщение с этим текстом в канал, либо сообщение priv. для кого-то это не очень важно сейчас. Я не могу найти какой-либо способ получить данные с первой фабрики и отправить их на другую, для обработки (может быть, как обычное полученное соединение для второй фабрики IRC?).

Если это можно каким-то образом решить, то я хотел бы добавить одну или несколько фабрик (например, Jabber) для отправки полученных данных через порт 8000 на все сразу, чтобы передать их соответствующим образом в протоколы (IRC для канал, Jabber для контакта и т. д.).

Есть ли кто-нибудь, кто сталкивался с подобной проблемой и готов дать мне какой-нибудь совет или даже поделиться некоторыми строками кода? Любая помощь будет высоко оценена!

Заранее спасибо.

Ответы [ 3 ]

6 голосов
/ 17 сентября 2010

Фабрики - это просто объекты.Чтобы передавать данные от одного к другому, вы определяете и вызываете методы и передаете данные как параметр или устанавливаете атрибуты.Я думаю, что этот часто задаваемый вопрос поможет вам:

Как сделать так, чтобы вход на одном соединении приводил к выходу на другом? Кажется, что это вопрос Twisted, но на самом деле это вопрос Python. Каждый объект Protocol представляет одно соединение;Вы можете вызвать его transport.write, чтобы записать в него некоторые данные.Это обычные объекты Python;вы можете поместить их в списки, словари или любую другую структуру данных, подходящую для вашего приложения.

В качестве простого примера, добавьте список к вашей фабрике, а также к connectionMade и connectionLost вашего протоколадобавить его и удалить из этого списка.Вот код Python:

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor

class MultiEcho(Protocol):
    def connectionMade(self):
        self.factory.echoers.append(self)
    def dataReceived(self, data):
        for echoer in self.factory.echoers:
            echoer.transport.write(data)
    def connectionLost(self, reason):
        self.factory.echoers.remove(self)

class MultiEchoFactory(Factory):
    protocol = MultiEcho
    def __init__(self):
        self.echoers = []

reactor.listenTCP(4321, MultiEchoFactory())
reactor.run()
0 голосов
/ 08 октября 2010

Я делаю это, создавая контейнерный класс.

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor

class QOTD(Protocol):

    def connectionMade(self):
        self.factory.message_siblings("Got a client")
        self.transport.loseConnection()

class MyFactory(Factory):
    protocol = QOTD
    def __init__(self,root,name):
        self.clients = []
        self.root = root
        self.name = name
        #self.root.add_child(name,self)
    def message_siblings(self,message):
        self.root.message_children(self.name,message)
    def message_sibling(self,message):
        self.root.message_child(self.name,message)  
    def get_message(self,name,message):
        #do something here
        print name,message



class Container(object):
    def __init__(self):
        self.servers = {}
    def add_child(self,obj,name):
        self.servers[name] = obj(self,name)
    def message_children(self,name,message):
        for server in self.servers:
            if server != name:
                self.servers[server].get_message(name,message)
    def message_child(self,name,message):
        if name in self.servers.keys():
            self.servers[server].get_message(name,message)

container = Container()
container.add_child(MyFactory,'test')
container.add_child(MyFactory,'test2')
reactor.listenTCP(8007, container.servers['test'])
reactor.listenTCP(8008, container.servers['test2'])
reactor.run()

Возможно, это не лучший метод, но он работает и допускает некоторую гибкость

0 голосов
/ 22 сентября 2010

Я думаю, что ваш комментарий выше в правильных строках - вам нужно иметь ссылку или «дескриптор» для объекта, которому вы хотите отправить данные.

Другими словами, отправляющий объект фабрики должениметь ссылку на принимающий объект фабрики, если вы хотите использовать связь объекта с объектом - то есть вызовы метода.Одним из способов достижения этого является передача имени фабрики-получателя фабрике-отправителю при инициализации.

Это не всегда очевидно из примеров, но фабрика может передавать данные при инициализации.Например, в приведенном выше примере строка, которая создает MultiEchoFactory, может быть изменена на:

 reactor.listenTCP(4321, MultiEchoFactory(someOtherObject))

, а сам объект MultiEchoFactory изменен в методе init :

class MultiEchoFactory(Factory):
    protocol = MultiEcho
    def __init__(self, otherObjectReference):
        self.echoers = []
        self.otherObject = otherObjectReference

Теперь у вас есть ссылка на другой объект и вызов метода для него.

Другой подход может заключаться в том, чтобы иметь совершенно отдельный объект, на который все ваши фабрики ссылаются при инициализации, и который действует каксвоего рода сервер поиска ссылок на объектные ссылки, когда один объект хочет говорить с другим.Эта функциональность может быть предоставлена ​​функцией, если вы не хотите использовать объект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...