我正在尝试学习如何使用Twisted进行操作,而且我有点坚持一个概念:制定一个基本上在两个不同阶段进行通信的协议:首先是短暂的握手和身份验证,然后是实际的工作。 / p>
我天真的做法是编写这样的协议:
def stringReceived(self, data):
if self.state == "authenticate":
handle_auth(data)
else:
handle_actual_work(data)
我很难搞清楚这样做的扭曲方式。以上是正常的吗?在我看来,编写一个执行身份验证的协议和另一个只处理经过身份验证的客户端的协议会更有意义,但我究竟会如何做到这一点?
我查看了类似的问题Twisted: How can I identify protocol on initial connection, then delegate to appropriate Protocol implementation?。给出的解决方案归结为与我目前的方法基本相同。这真的是正确的做法吗?
答案 0 :(得分: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)
......或者说得更漂亮,你可能想要使用装饰器,元类或其他东西。这些方法都没有错。