【问题标题】:Twisted: How can I identify protocol on initial connection, then delegate to appropriate Protocol implementation?Twisted:如何在初始连接上识别协议,然后委托给适当的协议实现?
【发布时间】:2012-02-29 15:40:04
【问题描述】:

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

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

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

【问题讨论】:

    标签: python twisted


    【解决方案1】:

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

    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/

    【讨论】:

      【解决方案2】:

      这很容易用一些魔法来完成。

      class MagicProtocol(Protocol):
          ...
          def dataReceived(self, data):
              protocol = self.decideProtocol(data)
              for attr in dir(protocol):
                  setattr(self, attr, getattr(protocol, attr))
      

      这很难看,但它会有效地将 Magic 协议切换为所选协议。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-13
        • 1970-01-01
        • 1970-01-01
        • 2010-12-19
        • 2023-03-14
        • 2014-10-23
        相关资源
        最近更新 更多