Twisted - 如何创建多协议进程并在协议之间发送数据

Posted

技术标签:

【中文标题】Twisted - 如何创建多协议进程并在协议之间发送数据【英文标题】:Twisted - how to create multi protocol process and send the data between the protocols 【发布时间】:2010-03-26 18:08:28 【问题描述】:

我正在尝试编写一个程序,该程序将在某个端口(例如 tcp 6666)上侦听数据(简单的文本消息),然后将它们传递给一个或多个不同的协议 - irc、xmpp 等。我尝试了很多方法并挖掘了互联网,但我无法为此类任务找到简单且有效的解决方案。

我目前正在使用的代码在这里:http://pastebin.com/ri7caXih

我想知道如何从像这样的对象:

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

获得对自身协议方法的访问权,因为:

self.protocol.dupa1(msg)

返回关于 self 未传递给活动协议对象的错误。或者也许有其他更好、更简单和更洁净的方法来创建具有多个协议的单个反应器,并在消息到达其中任何一个时触发动作,然后将该消息传递给其他协议进行处理/处理/发送?

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

这里是从多个连接读取到端口 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 上。

【讨论】:

【参考方案2】:

常见问题解答中对此进行了回答。

http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#HowdoImakeinputononeconnectionresultinoutputonanother

【讨论】:

不。该示例从所有人读取,写入所有人。原始海报(和我自己)正在寻找“从一堆中读取”写入“不同的一堆”。 只有“不”,因为它不是发布者想要的精确实现。这是一个例子,它不是一个解决方案。看看它并从中学习。你看不出你可以如何用其他一些选择标准替换所有客户端的循环吗? 还是不行。您需要从一个协议连接到另一个。这个例子只是展示了如何用一个协议重写。你真的否决了我的实际工作答案吗? 没问题,我的答案回0了。【参考方案3】:

doc/core/examples/chatserver.py。他们在那里为ProtocolconnectionMadeconnectionLost 方法添加了挂钩,以维护已连接客户端的列表,然后在消息到达时遍历所有客户端以进行传递。

【讨论】:

我认为,它不能解决我的问题 - 该示例的作用是向一个协议范围内的每个连接的客户端发送消息。我正在尝试做的是在某个端口上接收文本行,然后将其传递给两个或多个不同的协议,在接收消息时可以根据协议定义的方法对其进行处理 - 比如将接收到的行粘贴到 irc 通道,通过 xmpp 发送到 jabber 客户端,等等。 因此,您必须按照示例所做的那样,跟踪连接的客户端(在每个协议上),但还要添加一些更高级别的对象来跟踪所有这些.这可能是您创建的 Service,其中包含对您的 ircnagios 工厂的引用,并将消息传递给它们。 好吧 - 我似乎并没有简单地解释这个问题。此代码旨在侦听端口 6666 并同时作为机器人登录 irc(让我们暂时放弃 jabber 事物),它将在端口 6666 上接收到的消息发送到他将登录的 irc 通道。这不是在一个协议中的多个客户端之间发送消息的问题,而是在两个(或多个)独立协议/工厂之间传递数据的问题。我希望这有助于理解代码背后的问题。

以上是关于Twisted - 如何创建多协议进程并在协议之间发送数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用twisted通过UDP协议发送参数

如何从协议外部发送 Autobahn/Twisted WAMP 消息?

进程对象的其他方法守护进程使用多进程实现 socket tcp协议 server端的并发(抢票程序)队列进程之间的通信(IPC)

网络编程TCP/IP协议----- 多进程多线程服务器

Twisted 和 libtorrent - 我需要担心阻塞吗?

python twsited快速基础