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に登録されていません-すぐに登録されます。
サーバーはすぐに使用できます(願っています)-通常、小規模で閉じられたプロジェクトでスピンします。 すべてのプロトコルが機能するため、特別な驚きはありません。
ストレステスト、エラーの特定にご協力いただきありがとうございます。これが他の誰かに役立つことを願っています。