TornadIO2 =トルネード+ Socket.IO

Socket.IOとはですか?



これは、サーバーとブラウザー間の永続的な接続を確立するために設計されたライブラリです。



ライブラリの主な利点は、ブラウザの機能に合わせて自動的に調整し、サポートされている最も効率的なトランスポートプロトコルを使用することです。



ブラウザはWebソケットに対応していますか? 素晴らしい、それらを使用します。 ブラウザはAJAXの使用方法を知っていますか? 長いポーリングを使用します。 古代のInternet Explorerですか? htmlファイルオブジェクトを使用します。 まあなど。



socket.ioについて 、すでにHabréで書いています。 「ネイティブ」のSocket.IOサーバーは、node.jsで記述されています。



TornadIO2とは何ですか?



これは、Tornado上で実行され、現在のバージョンのSocket.IOプロトコルをサポートするライブラリです。



ライブラリの主な利点は、仮想接続を介した便利な抽象化を提供することです。そのため、開発者はさまざまな条件でトランスポートがどのように機能するかを考える必要がありません。



TornadIO2と呼ばれるのはなぜですか? 古いバージョンのSocket.IOと古いバージョンのTornado(1.2など)をサポートするTornadIOがあるためです。 Socket.IO 0.7以降、トランスポートプロトコルが変更され、最初のTornadIOのアーキテクチャに適合しない新しい機能が登場しました。 さらに、TornadIO2にはTornado 2.1以降が必要です。



プロジェクトのホームページはこちら: http : //github.com/MrJoes/tornadio2

ドキュメント(英語)はここにあります: http : //tornadio2.readthedocs.org/



コードにより近い



最も単純なSocket.IOクライアントは次のようになります。

var conn = io.connect('http://myserver'); conn.on('connect', function() { alert('connected'); }); conn.on('message', function(msg) { alert('Got ' + msg); }); conn.on('disconnect', function() { alert('disconnected'); });
      
      





大まかに言えば、接続オブジェクトを作成し、さまざまなイベントに反応を追加します。接続、メッセージの受信、サーバーからの切断です。



サーバーにメッセージを送信する場合、次のようにします。



 conn.send('Hello World!');
      
      







Socket.IOは、jsonオブジェクトの送信をサポートしています。



 conn.json.send({msg: 'Hello World', a: 10});
      
      







次に、単純なサーバーがどのように見えるかを見てみましょう。



 from tornado import web from tornadio2 import SocketConnection, TornadioRouter, SocketServer # Declare connection class class MyConnection(SocketConnection): def on_open(self, info): print 'Client connected' def on_message(self, msg): print 'Got', msg self.send(msg) def on_close(self): print 'Client disconnected' # Create TornadIO2 router router = TornadioRouter(MyConnection) # Create Tornado application with urls from router app = web.Application(router.urls, socket_io_port=8001) # Start server if __name__ == '__main__': SocketServer(app)
      
      







この例では、主要部分はMyConnectionです。 クライアントがサーバーに参加すると、TornadIO2はこのクラスをインスタンス化し、 on_open()を呼び出します。 サーバーは、クライアントからメッセージを受信すると、送信されたメッセージでon_messageを呼び出します。 などなど。



TornadioRouterは1つの接続クラスで動作し、socket.ioクライアントが正しく機能するために必要なすべてのネットワークロジックを実装します。



次に、Tornadoアプリケーションを作成し、ルーターからリンクをフィードして、サーバーを起動します。 SocketServerは、Tornado HTTPサーバーとFlash Policy Server 'aを起動してFlashSocketトランスポートをサポートするための便利なラッパーです。



文字列と通常のオブジェクトの両方を送信できます。主なことは、通常はJSONでシリアル化されることです。



イベント



Socket.IOの最新バージョンでは、イベントの概念が登場しました-「通常の」メッセージを送信する代わりに、関数呼び出しがエミュレートされ、RPCが取得されます。 当然、パラメーターの数(またはその名前)を間違えた場合、例外が発生し、接続が終了します。



イベントは次のように送出されます。



 var conn = io.connect('http://myserver:1234'); conn.on('connect', function() { conn.emit('hello', 'Joes'); });
      
      







そして、サーバー上で次のように処理されます。



 from tornadio2 import SocketConnection, event class MyConnection(SocketConnection): @event('hello') def hello(self, name): print 'Got hello from %s' % name
      
      







サーバーからイベントを送信し、クライアントでイベントを処理する方法も同様です。



 var conn = io.connect('http://myserver:1234'); conn.on('connect', function() { conn.emit('ping', 'Joes'); }); conn.on('pong', function(name) { alert(name); // Will show Joes });
      
      







そしてサーバー:



 from tornadio2 import SocketConnection, event class MyConnection(SocketConnection): @event('ping') def ping(self, name): self.emit('pong', name)
      
      







確認



メッセージまたはイベントを送信するとき、確認を求めることができます-メッセージが受信および処理されると、ACKパケットが自動的に送信され、転送されたコールバックが呼び出されます。

イベントの場合、ハンドラーから値を返すことができ、それが自動的にクライアントに送信されるため、REQUEST / RESPONSEパターンの便利なコードを取得します。



APIの観点から見ると、すべて次のようになります。



 var conn = io.connect('http://localhost'); conn.on('connect', function() { // Emit 'whoareyou' event and provide callback function that will be // called once event was handled by the server. conn.emit('whoareyou', function(name) { alert(name); // Will print 'Joes' }); });
      
      







そしてサーバー:



 class MyConnection(SocketConnection): @event('whoareyou') def woohoo(self): return 'Joes'
      
      







サーバーは、確認の必要があるメッセージを送信することもできます。 これを行うには、コールバックをself.send()に渡す 、イベントにself.emit_ack()を使用します。



 class MyConnection(SocketConnection): @event('hello') def myhello(self): self.emit_ack('hello', self.on_ack) def on_ack(self, msg, data): print 'Woohoo, got ACK', msg, data
      
      







Tornado.genのサポート



Tornadoバージョン2.1.0以降、コールバックなしで非同期コードを作成するための便利なインターフェイスが登場しました。



tornado.genを使用する場合、コードは非同期で動作します。クライアントから2つのメッセージを受信し、最初のメッセージが非同期で処理される場合、2番目のメッセージは最初のメッセージが処理を完了する前に処理されます。 これは常にサーバーに期待されるものではありません。



tornadio2.gen.sync_engineデコレータは、これらの目的のために特別に作成されました。



デコレータでメッセージ(またはイベント)ハンドラをラップすると、メッセージは受信した順に処理されますが、ioloopはブロックされません。



これがすべてどのように機能するかを示すを見るのが最善です。



パフォーマンスモニター



TornadIO2には、アクティブな接続の数、1秒あたりの送受信メッセージ数など、さまざまなイベントをカウントするシンプルなモニターが含まれています。 カウンターのリストはまだそれほど大きくないので、私は喜んで喜んでいます。



データの操作方法を示す簡単ながあります。グラフを作成し、次のようなリアルタイム統計を表示します。





性能



残念ながら、ライブラリの完全な負荷テストはまだ実行されていないため、パフォーマンスについて実際の数値を作成することはできません。 誰もがテストしたい場合、私は非常に感謝します。



サーバーコードは十分に軽量であり、オーバーヘッドはそれほど顕著ではありません。





TornadIO2には、簡単なチャット、socket.ioを介したpingなど、いくつかの使用例が含まれています。

すべての例はこちらです。



現状と将来



TornadIO2はまだPyPIに登録されていません-すぐに登録されます。



サーバーはすぐに使用できます(願っています)-通常、小規模で閉じられたプロジェクトでスピンします。 すべてのプロトコルが機能するため、特別な驚きはありません。



ストレステスト、エラーの特定にご協力いただきありがとうございます。これが他の誰かに役立つことを願っています。



All Articles