twistedをさわってみる
pyapnsのソースを追っかけてたんだけど、どうも読みにくい。
これは多分使われているtwistedについて何も知らないからだ。
せっかくだから入門してみよう。
ということでよく見かけるEchoサーバーを書いて動かしてみた
# coding=utf-8 from twisted.internet import protocol, reactor from twisted.internet.protocol import connectionDone class UpperEcho(protocol.Protocol): """クライアントとデータの処理 """ def dataReceived(self, data): print self.transport.__class__ # => <class 'twisted.internet.tcp.Server'> self.transport.write(data.upper()) def connectionMade(self): print 'connectionMade: connected' def connectionLost(self, reason=connectionDone): print 'connectionLost connected' print reason # => [Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly. # ] class UpperEchoFactory(protocol.Factory): """クライアントの接続とプロトコルの管理 """ def buildProtocol(self, addr): print addr # => IPv4Address(TCP, '127.0.0.1', 54956) return UpperEcho() if __name__ == '__main__': reactor.listenTCP(1234, UpperEchoFactory()) reactor.run()
コンソールからtelnet localhost 1234で接続でき、タイプした文字のuppercaseが表示される
以下メモ
1. reactor.listenTCPにポート番号とprotocol.Factoryを継承したクラスのインスタンスを渡す
Factoryは「クライアントの接続とプロトコルの管理」を行う。
2. 接続がくるとFactoryのbuildProtocolが呼ばれ、protocol.Protocolを継承したクラスのインスタンスを返す
attrには接続元情報を保持しているインスタンスが渡されるようだ
3. Protocolのインスタンスを作成する際に、クライアントに接続し、接続後にconnectionMadeが呼ばれる
4. telnetに入力をするとdataReceivedが呼ばれる
Protocolが保持しているtransportはtwisted.internet.tcp.Serverのインスタンスでこいつのwriteメソッドに文字列を渡すことでクライアントにレスポンス、この場合はuppercaseを返せる
5. コンソール側で接続を切るとconnectionLostが呼ばれる
reasonという引数が渡されるが、printしてみると以下のような文字列だった
[Failure instance: Traceback (failure with no frames): <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly. # ]
なんかエラーっぽいようなエラーっぽくないような。。正常に接続が切れたと思ってよいのだろうか