Twisted:如何在初始连接时识别协议,然后委托给适当的协议实现? [英] Twisted: How can I identify protocol on initial connection, then delegate to appropriate Protocol implementation?

查看:25
本文介绍了Twisted:如何在初始连接时识别协议,然后委托给适当的协议实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 Python 程序,它将使用 Twisted 连接到 TCP 服务器.套接字另一端的服务器可能正在运行两种可能的协议(protoA 或 protoB)中的一种,但在我启动连接并询问"服务器正在使用哪种协议之前,我不知道它是哪一种用过的.连接后,我能够确定使用的是哪个版本的协议(protoA 或 protoB),但我不知道提前.

I'm writing a Python program that will use Twisted to connect to a TCP server. The server on the other end of the socket might be running one of two possible protocols (protoA or protoB), but I won't know which one it is until I've initiated the connection and "asked" the server which protocol is being used. I'm able to identify which version of the protocol (protoA or protoB) is being used once I've connected, but I don't know it ahead of time.

显然,一种解决方案是在我的扭曲协议派生类中包含大量特殊情况代码——即,如果 protoA 执行此操作,则 elif protoB 执行其他操作.但是,我希望能够在两个单独的协议实现中保留两个单独协议的代码(尽管它们可能通过基类共享某些功能).由于协议的两个版本都涉及维护状态,因此必须将两个版本混合到同一个类中很快就会让人感到困惑.

Obviously, one solution is to have a lot of special-case code in my twisted Protocol-derived class -- i.e. if protoA do this elif protoB do something else. However, I'd like to be able to keep the code for the two separate protocols in two separate Protocol implementations (though they might share some functionality through a base class). Since both versions of the protocol involve maintaining state, it could quickly get confusing to have to mash both versions into the same class.

我该怎么做?有没有办法在工厂实现中做最初的协议识别"步骤,然后实例化正确的协议派生?

How can I do this? Is there a way to perhaps do the initial "protocol identification" step in the Factory implementation, then instantiate the correct Protocol derivative?

推荐答案

不要在整个协议实现中混合决策逻辑,而是将其放在一个地方.

Instead of mixing the decision logic all throughout your protocol implementation, put it in one place.

class DecisionProtocol(Protocol):
    def connectionMade(self):
        self.state = "undecided"

    def makeProgressTowardsDecision(self, bytes):
        # Do some stuff, eventually return ProtoA() or ProtoB()

    def dataReceived(self, bytes):
        if self.state == "undecided":
            proto, extra = self.makeProgressTowardsDecision(bytes)
            if proto is not None:
                self.state = "decided"
                self.decidedOnProtocol = proto
                self.decidedOnProtocol.makeConnection(self.transport)
                if extra:
                    self.decidedOnProtocol.dataReceived(extra)

        else:
            self.decidedOnProtocol.dataReceived(bytes)

    def connectionLost(self, reason):
        if self.state == "decided":
            self.decidedOnProtocol.connectionLost(reason)

最终你可以用更少的样板来实现这个:http://tm.tl/3204/

Eventually you may be able to implement this with a bit less boilerplate: http://tm.tl/3204/

这篇关于Twisted:如何在初始连接时识别协议,然后委托给适当的协议实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆