3

我正在尝试学习如何使用 Twisted 做一些事情,但我有点坚持一个概念:制作一个基本上在两个独立阶段进行通信的协议:首先是短暂的握手和身份验证,然后是实际工作。

我天真的方法是编写这样的协议:

def stringReceived(self, data):
    if self.state == "authenticate":
        handle_auth(data)
    else:
        handle_actual_work(data)

我很难弄清楚这样做的扭曲方式。以上正常吗?在我看来,编写一个进行身份验证的协议和另一个只处理经过身份验证的客户端的协议会更有意义,但我究竟该怎么做呢?

我查看了类似的问题Twisted:如何在初始连接时识别协议,然后委托给适当的协议实现?. 那里给出的解决方案归结为与我目前的方法基本相同。这真的是正确的方法吗?

4

1 回答 1

3

是的,你的版本很正常。可以说 Twisted 应该对状态机有更多的支持,因为它在内部为不同的协议、不同的事件星座等提供了大约 100 种不同的这种通用模式的实现。但这部分本身并不是 Twisted 的工作:Twisted 正在暴露你的网络对象,并且将在其上调用方法(在本例中为stringReceived)。您对该消息的处理完全取决于您的对象,并且if声明是完全合理的事情:)。

在这个级别上,问题实际上并不是关于“扭曲的方式”,而是关于状态机和依赖于上下文的方法的更好的 Python 习惯用法。根据您的协议的确切需求,您当前的方法可能很好,或者您可能希望分派到具有特殊名称的方法,如下所示:

def stringReceived(self, data):
    getattr(self, "stringReceived_{}".format(self.state))(data)

def stringReceived_authenticate(self, data):
    if self.auth_ok(data):
       self.state = 'normal'
    else:
       self.transport.loseConnection()

def stringReceived_normal(self, data):
    self.do_stuff(data)

... 或者变得更花哨,您可能想要使用装饰器、元类或其他东西。这些方法都没有错。

于 2012-05-09T22:32:25.713 回答