プログラミングのこと、Pythonのこと、気になったソフトウェアのこと、身の回りのこと、いろんなこと。ページホームwiki2010年12月22日WebSocketのサーバ間でメッセージをリレーさせるサンプルどうもです。Pythonのアドベントカレンダーに参加することになっていましたおおたにです。お題が、PythonのWebフレームワークです。えっ、Webフレームワーク?僕はそんなにWebフレームワーク詳しくないし・・・。数年前ならまだしも、最近は便利に使えれば後はそれほど気にしなくなっていました。Webフレームワーク・・・。flaskってやっていない罠が・・・。いうことで、前置き(言い訳)が長くなりました、WebSocketのサーバを複数立てたときに、サーバ間のデータのやりとりをどうするのかというお話です。WebSocketはHTML5関連で脚光を浴びている機能なので、知っている人も多いでしょう。簡単にいってしまえば、最初にHTTPプロトコルを偽装して、その後データのだだ漏れができるものです。Chromeでは去年サポートされ、Safariも今の最新版でサポートされています。iOS4.2.1でもサポートされているのでiPhoneからでも使えます。IE9では、「何それ?」の悲しい状態ですが、プロトコルの不安定さから仕方ないですね。Firefoxは4からサポートすると期待させておきながら、こんな残念な記事が今朝聞こえてきました。WebSocketでデータの送受信をすると、Cometなどのロングポーリングよりはインフラに優しい作りになります。ロングポーリングでも同じですが、アプリケーションサーバを複数立てたとき、アプリケーションサーバ間でデータをやりとりする必要がでてきます。リアルタイム性が大きなメリットなので、データベースとかは介せません。Waveが消えたのと、ブログの一つのエントリじゃ収まらないので、XMPPは忘れます。自前で作るとしたらハブサーバを作って、アプリケーションサーバとハブサーバの間でデータの垂れ流し(リレー)をさせるのが良さそうです。そのときのプロトコルもWebSocketで中身はJSONとか、MessagePackとかもいいかな、と思ったのですが、サンプルコードはライブラリを調べる時間も含めて30分以内に作らないといけないというローカルルールにより、行ベースで自分でソケットを開きます。今回のサンプルは全部geventベースで書いています。非同期処理が同期処理のように書けるのがすごいメリットです。WSGIサーバにもなるので、FlaskでもDjangoでも使えます。WebSocketを非同期にこだわるかはむか〜し、どこかで書いた気がするので省略。今回のサンプルはある程度ブロックするので効率は悪いです。サンプルコードはここにあります。ハブサーバのコードです。server.serve_forever()geventのsocketが標準ライブラリのsocketと全く同じようにあつかえます。メッセージを垂れ流しているだけなので、単純です。Webアプリケーションの方は、以前のコードとほとんど同じなので、ポイントだけ。全部読みたければ、これ。chat_clients.remove(ws)fileobjはハブサーバに接続した後にsocket.makefileしたものです。これだけでメッセージをリレーしてくれます。えっ?信じられないって?それじゃ、動いている画像です。そこで有力なのがXMPPだと信じていますが、ぜひAMQPで作ってください。さんのコメント...うっ、AMQPは忘れていました。拡張forループでループの回数も同時に欲しいよね。