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

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

我怎样才能做到这一点?有没有办法在工厂实现中进行初始“协议(protocol)识别”步骤,然后实例化正确的协议(protocol)派生类?

最佳答案

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

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/

关于python - Twisted:如何在初始连接时识别协议(protocol),然后委托(delegate)给适当的协议(protocol)实现?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9502090/

10-13 00:57
查看更多