はじめに
「Socket.io = リアルタイムなWebアプリを作れる」ぐらいの認識しか無かったので、そもそもリアルタイムWebアプリを実現する技術には何があるのか、Socket.ioを使うと何が嬉しいのかまとめてみました。
リアルタイムWeb技術の遷移
ポーリングを用いる手法
ポーリングとは (Wikipediaから引用)
通信やソフトウェアにおいて、競合を回避したり、送受信の準備状況を判断したり、処理を同期したりするために、複数の機器やプログラムに対して順番に定期的に問い合わせを行い、一定の条件を満たした場合に送受信や処理を行う通信及び処理方式のこと
つまり、この場合だとサーバー側に変更等のイベントがあったか、AjaxによるHTTPリクエストを繰り返し行って確認する方法のことを指します。
一番シンプルですが、サーバー側のイベントを追随するために、頻繁にポーリングしなければならず、ネットワーク帯域とサーバリソースを無駄に消費してしまいます。
クライアント数が増えれば増えるほど、問題となりスケール出来ない手法なので、よほどの限りは使わない方が良いでしょう。
Cometを用いる手法(ロングポーリング, ストリーミング)
2つ目がCometです。Cometとは「サーバー側から本当に必要なタイミングでレスポンスを返せるように考えられた手法」の総称です。
ここでは、まずポーリングを少し変更することで容易に実現できる、ロングポーリングと呼ばれる手法から紹介します。
ロングポーリング
一般的なHTTP通信では、クライアントからのリクエストを受け取ると、サーバーはすぐにレスポンスを返して、コネクションを切断します。
ロングポーリングでは、クライアントからのリクエストに対して、サーバーはレスポンスを保留して、コネクションを維持します。
そして、サーバー側でイベントが発生した時に維持していたコネクションを利用してHTTPレスポンスを返すことでリアルタイムに情報を送信することを可能にしています。
ロングポーリングでは、一度確立したコネクションを維持するため、サーバー側で同時接続数・キープアライブの設定を大きめに設定します。
ただし、コネクションを維持することによるメモリ使用量の増加など、状況によってはデメリットもあるので利用に関しては、慎重に検討する必要があります。
ストリーミング
ロングポーリングでは、キープアライブで設定していたタイムアウトの時間になるとコネクションが切断されます。
対するストリーミングでは、一度確立したコネクションを維持したまま、サーバー側からクライアントへレスポンスを返し続けます。明確に切断しなければそのままずっと接続されます。
ストリーミングでサーバーからのプッシュ通信を実現するには、クライアント側でレスポンスを受信しながら内容を解析して適切に処理する必要があります。
実現方法は「Server-Sent Events」という仕様がW3Cによってきちんと定義されています。
Server-Sent Eventsの特徴は、仕様に従った形式でサーバーサイドから通常のHTTPレスポンスを返すだけで、プッシュ通信が実現できるため、既存のHTTP通信の範疇で実装することが出来るという点です。
気になる方は一度以下のドキュメントを読んでみてください。
Server-Sent Events の利用 - Server-sent events | MDN https://developer.mozilla.org/ja/docs/Server-sent_events/Using_server-sent_events
Web Socket
WebSocketとはIETFがRFC6455として標準化した「JavaScriptからサーバーとの双方向通信を行う」ためのプロトコルです。
元々はHTML5の仕様の一部として進められていましたが、現在では単独のプロトコルとして策定されています。
仕様に沿って実装すれば、比較的簡単に双方向通信を利用したリアルタイムWebアプリケーションが実現出来ます。
WebSocket用のプロトコルを使っているため、利用できるかはブラウザによります。
モダンブラウザ(Firefox, Chrome, Safari)ではほぼ問題無く利用が出来ますが、
IE9以下、Firefoxの古いバージョンでは一部利用できないようです。
ブラウザの対応状況に関しては、以下のサイトが参考になります。
Can I use... Support tables for HTML5, CSS3, etc http://caniuse.com/#feat=websockets
Socket.ioの登場
これまで見てきた通り、リアルタイムWebアプリケーションを実現する技術には様々な実装があり、状況によって使い分ける必要があります。
Socket.ioはそうした「複雑なリアルタイムWeb技術の実装方式を隠蔽し、すべてのブラウザ・モバイルデバイスでリアルタイム通信を可能とすること」を目的に開発されているnode.js用サーバー側ライブラリとブラウザ用JavaScriptライブラリのセットです。
今まで紹介してきた各技術(ポーリング、Comet、Web Socket)に対応しており、いずれも同じSocket.io APIから利用することが出来ます。
そのため、Socket.io APIを利用してサーバー側・ブラウザ側の実装を行えば、ユーザーの利用しているOSやブラウザによって、最適なリアルタイムWeb技術が選択され、幅広い環境からリアルタイム通信を行うことが可能になります。
以下のURLから、Socket.ioのデモを見ることが出来ます。複数のブラウザ、デバイスから同時にアクセスしてみてください。全て同時に更新されます!驚きです。
Socket.IO — Chat [http://socket.io/demos/chat/]
(http://socket.io/demos/chat/ "http://socket.io/demos/chat/"0)
また最近ではJavaScript以外の言語でも、Socket.io APIが利用できるようになっているようです。
今回の調査でSocket.ioの概要について理解できたので、次回はより実践的な使い方についてご紹介したいと思います。