3

Twistedを使って何かをする方法を学ぼうとしていますが、基本的に2つの別々のフェーズで通信するプロトコルを作成するという1つの概念に固執しています。最初に短いハンドシェイクと認証、次に実際の作業です。

私の素朴なアプローチは、次のようなプロトコルを作成することです。

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

私はこれを行うためのねじれた方法を理解するのに苦労しています。上記は正常ですか?認証を行うプロトコルと、認証されたクライアントのみを処理するプロトコルを作成する方がはるかに理にかなっているように思われますが、正確には、どのようにそれを行うのでしょうか。

同様の質問Twistedを調べました。最初の接続でプロトコルを識別してから、適切なプロトコルの実装に委任するにはどうすればよいですか?。そこで与えられた解決策は、基本的に私の現在のアプローチと同じになります。これは本当に適切なアプローチですか?

4

1 に答える 1

3

はい、あなたのバージョンはかなり正常です。おそらく、Twistedは、さまざまなプロトコル、さまざまなイベントコンステレーションなどに対して、この一般的なパターンの約100の異なる実装を内部的に持っているため、ステートマシンをより多くサポートする必要があります。しかし、この部分は、実際には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 に答える