编程语言
首页 > 编程语言> > Twisted Python:将协议与处理分开

Twisted Python:将协议与处理分开

作者:互联网

我想实现一个自己的基于TCP的协议,以在Twisted之上的服务器中使用.这种协议实现的机制很明确(继承自Protocol,并覆盖了四个继承的方法,即建立Factory).

但是,我希望我的协议与应用程序逻辑分开,其方式是:

>协议:从客户端接收数据,解码字节流并填充Python数据结构,获取数据结构,编码为字节流(基于文本)并响应客户端
>应用逻辑:接收所述数据结构,评估并返回响应数据结构

如何以一种不依赖另一个的方式(即松散耦合)构建Twisted应用程序?我以为协议类将使用应用程序逻辑回调作为参数实例化?

编辑:

同时,我有这个:

from twisted.internet.protocol import Protocol
from twisted.internet.protocol import Factory
from twisted.internet.endpoints import TCP4ServerEndpoint
from twisted.internet import reactor

class Logic:
    def process(self, data):
        return "Processed: %s" % data

class LineProtocol(Protocol):
    def dataReceived(self, data):
        print "Received: %s" % data
        if self.factory._logic_callback:
            ret = self.factory._logic_callback.process(data)
            print "Sent: %s" % ret
            self.transport.write(ret)

class LineFactory(Factory):
    protocol = LineProtocol

    def __init__(self, logic_callback = None):
        if logic_callback:
            self._logic_callback = logic_callback()
        else:
            self._logic_callback = None

endpoint = TCP4ServerEndpoint(reactor, 1234)
endpoint.listen(LineFactory(Logic))
reactor.run()

您会认为这是“扭曲”的方式吗?有什么需要改进的吗?

该代码在LineFactory内部创建一个Logic实例.放在那里好吗?

解决方法:

请注意,您的计划中已经有一个松散耦合的示例.处理TCP实现细节的传输与协议是分开的,并且两个对象通过定义明确的接口进行交互:协议上的dataReceived等,传输上的write等.

只需将此想法再扩展一步即可.通过定义明确的接口让您的应用程序对象和协议交互.是否将应用程序对象作为__init__参数提供给协议,在某种程度上取决于预期的交互作用.如果应用程序是纯粹反应性的(即,它只是对协议上发生的事情做出反应,它本身不会启动事情),那么这是一个很好的方法.如果应用程序对驱动操作更感兴趣(例如,考虑一个驱动HTTP客户端协议的应用程序:在应用程序决定要发送请求之前,网络上什么都没有发生),那么您可能需要明确定义一个接口为使您的协议具有应用程序预期使用的协议(例如,HTTP客户端协议可能具有采用URL的请求方法,HTTP方法等).

请记住,有一些好的API可以带给您一个新的协议实例.例如:

from sys import argv

from twisted.internet.protocol import Protocol
from twisted.internet.endpoints import connectProtocol, clientFromString
from twisted.internet.task import react

def main(reactor, description):
    endpoint = clientFromString(reactor, description)
    connecting = connectProtocol(endpoint, Protocol())
    def connected(protocol):
        # Now `protocol` is connected somewhere and you can start
        # calling useful methods on it, if it has any.
        ...
    connecting.addCallback(connected)
    return connecting

react(main, argv[1:])

将一些有用的代码放到connect中,用更有趣的协议类的实例替换Protocol(),然后以an argument like“ tcp:localhost:25”运行.

从您的示例:

def dataReceived(self, data):
    print "Received: %s" % data
    if self.factory._logic_callback:
        ret = self.factory._logic_callback.process(data)
        print "Sent: %s" % ret
        self.transport.write(ret)

这不是真的有好处.您实际上尚未在协议中实现任何协议逻辑.您要做的只是让self.factory._logic_callback负责实现协议.这是几个额外的对象,没有真正的好处.我不建议这样做.

您想在协议类中进行所有解析和序列化.仅将根据结构化对象(执行任何解析的输出)实现的高层逻辑委托给协议以外的其他事物.

标签:protocols,twisted,python
来源: https://codeday.me/bug/20191122/2057789.html