Block Rockin’ Codes

back with another one of those block rockin' codes

Socket.IO アップデートと新プロダクト(Q-conf 編)

追記

11/11/22
コメントに頂いた Draft とフォールバックの表記を修正

本文

この手の話に統一したタイトルが欲しいんですが、先が見通せないのでどういうタイトルがいいのかわからないでいます。。
今回は最近の Socket.IO 周辺のアップデートについてまとめます。

QConf@SF

まず、 Qconf@SF で Guillermo が Socket.IO について重要なトークをしています。
資料は以下。

http://qcon-sf.nodejitsu.com/

この発表とともに LearnBoost はいくつかの新プロダクトを発表しました。


これらは、 Socket.IO について非常に重要な変更です。
それぞれのコンセプトと役割を解説します。

WebSocket.IO

内容

Socket.IO で使われていた、WebSocket の抽象レイヤを切り出したものです。
WebSocket の多くのプロトコル(Hixie,Hybi)をサポートし、
ハイレベルなフレームワークが、内部に組み込みやすいような API を提供しています。
特に「速度」を重視しているので、「Benchmark-driven releases」という方針を取るようです。


サポートするプロトコルは以下。

  • Draft-75
  • Draft-76
  • Draft-00
  • Protocol version 7
  • Protocol version 8
  • Protocol version 13
捕捉

Socket.IO は接続してきたブラウザが、使用可能な転送方法(ws, XHR, Flash etc) によって、フォールバックし、同じ API での通信を可能にしていました。
WebSocket.IO はそのうちの、 WS のエンジンを切り出したものです。
ただの、 WS API のラッパーではないのは、 WS 仕様策定の過程で実装されてきた多くのプロトコル実装(Hixie,Hybi) に対応しているため、
「WS を実装したブラウザ」なら、多少古くても統一された API で動くというもの。
おそらく、新しい仕様が出ても、ここにそのパーサを追加することで、依存する全てのフレームワークで最新の WS プロトコルに対応できるということです。
もちろん単体でも使えます。ただし、ある種のローレベル API 提供なので、 broadcast, Auth などは上位のフレームワーク(Socket.IO etc) で実装することになります。

engine.io

内容

Socket.IO の「トランスポートフォールバック」のレイヤを切り出したものです。

方針は以下

  • Isomorphic with WebSocket.IO.
    • WebSocket.IO と同じ API で、require の差し替えだけで、切り替えられる。
  • 信頼性の向上(どんな状況でもコネクションを張れるようにする)
  • 最小のクライアントサイズ
    • flash ファイルの遅延ロード
    • 余計なファイルは送らない
  • スケーラブル
    • ロードバランサとの相性


サポートする通信

  • polling: XHR / JSONP polling transport.
  • websocket: WebSocket transport.
  • flashsocket: WebSocket transport backed by flash
捕捉

このプロダクトの位置づけは、 Socket.IO がより「実用性」「信頼性」を重視し始めた意味で、とても重要なものです。
Socket.IO はこれまで、 WebSocket の通信を最初に試みて、だめだったら polling や Flash にフォールバックしていました。
しかし、これでは「フォールバックする」場合の方が多く、その時最悪のケースで10秒程度の遅延が起こることがありました。
例えば、 Socket.IO のチームが調査した結果では、いくつかのアンチウイルス/パーソナルファイアウォールでは、コネクションが確立できないことがわかっていました。
調査結果は Wiki にあります。

原文
Socket.IO and firewall software · LearnBoost/socket.io Wiki · GitHub
翻訳
Socket.IO and firewall software · Jxck/socket.io Wiki · GitHub

また、 Heroku などの PaaS が、 Node.js をサポートしていても、 WebSocket をサポートしていないケースもわかっています。

Engine.IO は最初のコネクションを Long Polling にすることで通信を確立し、その裏側で他の通信をテストして、より良い方法が可能であればフォールバックする。
というシステムに変更しています。
これにより、メッセージの取りこぼしが無いフォールバックが可能になります。

また、最初に必要になるクライアントライブラリを Long Polling に必要な最小限のものにすることで容量を削減します。
もし Flash が必要になった場合は、その重たいクライアントは遅延ロードで後からとってくることで無駄を省きます。
こうしたアーキテクチャの変化が、パフォーマンスの向上にも寄与しています。


その他

この変更の生まれる過程で、二つのサポートプロダクトが公開されています。

browserbuild

後者は、Node.js の require() を吸収し、Node.js 用に書かれたスクリプトをブラウザで使用できようにビルドするためのツールです。
Engine.io の isomorphic なライブラリを実現するために使われているようです。

latecy.io

Socket.IO のレイテシを測定し、グラフィカルに表示してくれるものです。
QConf の発表では、スライドに測定結果が埋め込まれていたようです。
hakobera さんが heroku で動かしているデモがこちらです。http://furious-spring-2336.herokuapp.com/

まとめ

執筆時点での Socket.IO@0.8.7 では、まだ dependencies には追加されていませんが、
将来的には、


Socket.IO > Engine.IO > WebSocket.IO の依存関係になると予想されます。


この変更は、大きくなった Socket.IO の内部構造を整理し、目的に特化したモジュールに分ける目的が大きいと思います。
そのメリットは以下のようなものでしょうか。

  • 各モジュールのメンテナンスをしやすくする。
  • 他のプロダクトでその一部に依存したライブラリを書ける(例えば Socket.IO レベルのレイヤのオリジナルライブラリ)
  • プロダクトを小さく保つ


先日発表された Flatiron でもそうですが、 Node.js では大きなフルスタック FW より、小さなライブラリを組み合わせる方法を取る場合が多いです。
また、自分が BSJS と言っていた「サーバとクライアントで同じ言語が使える」という点をメリットを捉える動きは、
"isomorphic javascript" という名前とともに広まりつつあるようです。(この単語の是非もありますが、今はこの流れ)。


Socket.IO の次期アップデートでこうしたものが統合されていくでしょう。
恐らく Socket.IO もこれまでのノウハウを振り返って、ビジネスも含めた多くのニーズを吸い込むことで、
より上質なリアルタイム通信モジュールを目指しているものと思います。
v1.0 に向けた大きな躍進になるでしょう。
今後も注目していきたいところです。