連載:人気順に説明する初めてのHTML5開発

双方向通信を実現! WebSocketを使いこなそう

WINGSプロジェクト ナオキ(監修:山田祥寛)
2011/11/11
2011/11/14 更新
2011/11/21 更新
Page1 Page2

  近年、ブラウザ上では当たり前のようにAjaxCometを利用した、リアルタイムな表示の更新や、通信が行われている。それぞれの特徴を簡単に記載すると以下のとおりだ。

(1)Ajax
  XmlHttpRequestオブジェクト(JavaScript)を利用した非同期通信処理のこと。Googleマップを筆頭とするWebアプリケーションで活用されている。ブラウザからサーバ側に非同期でリクエストを実施してデータを受け取り、JavaScriptにより部分的にページを更新することで、ページ全体を更新するよりも低負荷でサーバと通信できる。また、通信中も操作を継続できるので、エンド・ユーザーの操作を妨げられることもなく、ユーザビリティに優れる。デメリットとして、基本的にブラウザからのリクエストで動作する仕組みなので、サーバ側から自動でデータを送信することはない。

(2)Comet
 Ajaxのデメリットである、ブラウザからのリクエストで動作する仕組みではなく、サーバ側からクライアント側にレスポンスを返すための仕組み。チャット・サービス「Lingr」で活用されていた例が有名。Ajaxの応用として利用されていたが、サーバ側で意図的にリクエストに対する保留状態を作り、サーバ側で何かしらの変更が発生した場合にレスポンスを返す仕組みのため、Ajaxに比べてリソース消費が大きいというデメリットもあった。

 既存のWebアプリケーションを利用していると、「この2つがあれば十分だ」と錯覚しがちだが、リアルタイム性をより重視するWebアプリケーションを開発しようとする場合にAjaxとComet、それぞれのデメリット部分がネックになってきていた。また、それぞれHTTPリクエストを利用しているため、通信のたびにHTTPヘッダが付与されることでコネクション数に比例してトラフィックやリソース消費の増大も懸念されてきた。

WebSocketとは?

 そこでHTML5では、「WebSocket」と呼ばれる新たな通信規格が追加された。WebSocketを利用することで、AjaxやCometの通信におけるデメリット部分を補い、より効率的にサーバとクライアント間の双方向通信ができるようになる。WebSocketの特長は、以下の点だ。

  • サーバとクライアント間は一度でも接続が確立すると、明示的に切断しない限り通信手順を意識することなくデータのやり取りをソケット通信で実施できる
  • WebSocketで接続が確立しているサーバとすべてのクライアントは同じデータを共有し、リアルタイムで送受信できる

 図1〜2は、従来の通信技術とWebSocketを比較したものだ。

図1 WebSocket利用前の通信

 前述のとおり、従来の通信技術は通信のたびにHTTPヘッダが付与されるので、コネクションの数に応じてデータの送受信のほかに、わずかではあるがトラフィックが発生したりリソースが消費されたりしていた。

図2 WebSocket通信の概要図

 WebSocketは最初の接続時にそれ以降そのコネクションを使い続けるためにクライアントサイドからハンドシェイク要求を送る。サーバ側はハンドシェイク応答を返すことで1つのコネクションを使用し、続ける仕組みになっている。

 図3はハンドシェイク要求時のリクエストとレスポンスのヘッダだ。

図3 WebSocket接続時(=ハンドシェイク要求時)のリクエストとレスポンス・ヘッダ

 リクエストとレスポンス・ヘッダの中で重要なポイントは大きく4つある。

(1) WebSocketの接続先を指定する「Host」
(2)ハンドシェイク応答を得るための「Sec-WebSocket-Key」
(Sec-WebSocket-Keyの値からSec-WebSocket-Acceptの値を作成する)
(3)クライアントとのコネクションを維持するための「Sec-WebSocket-Accept」
(4)WebSocketのバージョンを指定する「Sec-WebSocket-Version」

 以上のリクエストとレスポンス・ヘッダにより、WebSocketによる接続が確立される。

 繰り返しになるが、WebSocketはハンドシェイクが成功した後は通信手順を意識することなくサーバとクライアントで双方向のデータの通信を実現できるので、従来では工夫して実現していたリアルタイム性を求めるアプリケーションをより簡単に実現できる。

WebSocketの実装状況

 WebSocketは、HTML5の中でも互換性なくドラフトが改訂されている状態が長く続いたAPIであり、古いドラフトのものではセキュリティ・ホールが報告されていた。そのため、FirefoxやOperaではWebSocketの機能を無効にするなどの対応が取られていた。

 以下の表はWebSocketプロトコルのラストコール(=最終勧告)となるDraft(draft-ietf-hybi-thewebsocketprotocol-10)以降のDraft(=仕様の草案)に対応しているブラウザだ。WebSocketプロトコルはラストコール以降も改訂が勧められ、2011年11月の段階でhybi-17まで改訂が進んでいる。

 現在、リリースされている主要ブラウザではChromeとFirefoxのみの実装となるが、2011年9月29日付で、WebApps Working Groupから、WebSocket APIの草案もラストコールとして公開されている。今後、多くのブラウザでWebSocketが正式に実装されていくだろう。

ブラウザ 対応バージョン
Internet Explorer 未実装
Firefox 7以降
Chrome 14以降
Safari 未実装
Opera 未実装
主要ブラウザにおけるWebSocketの実装状況
なお、2011年11月の段階ではFirefoxでWebSocketを利用する際にWebSocketではなく、「MozWebSocket」と記載する必要がある。

 IEでは、次期バージョンとなる「10」からWebSocketが正式に対応される予定だ。また、それ以外のブラウザもこれからリリースされるバージョン以降がラストコール対応版となるだろう。

 なお、今回のサンプルはこれまでの連載と違い、未実装なブラウザが多い点やドラフト依存の部分があるため、オンライン上での掲載はしない点に理解していただきたい。サンプルはサーバ側の.exeファイルを実行後、WebSocketClient.htmファイルをChromeで複数起動することで動作を確認できる。サーバ側の準備については後述する。

WebSocketを利用しているサービス

 実際にWebSocketを利用しているサービスやデモを2つ紹介する。

(1)Hummingbird
 Hummingbirdはオープンソースのアクセス解析ツールで、アクセス結果を、WebSocketを利用してリアルタイムで参照できるのがウリだ(下の画面を参照)。

図4 Hummingbirdのアクセス解析例

(2)Web Socket Chat
 Web Socket Chatは、マイクロソフトが提供予定のWebSocketサーバ“WCF WebSockets”を利用したチャット・アプリケーションのデモ・サイトだ。図5はそのデモ・サイトで2つのブラウザを開いてチャットをしている例である。

図5 Web Socket Chatを利用した双方向通信例

 今回は、サーバサイドにこのWCF WebSocketsとWeb Socket Chatの一部を利用し、サンプルを構築する。

WebSocket対応のサーバ・プロダクト

 WebSocketを利用したアプリケーション開発には、WebSocketの機能を盛り込んだサーバサイド実装のプロダクトが必要だ。WebSocketを実装しているプロダクトは以下のとおり。

プロダクト 概要
Jetty Javaで作成されたWebサーバで、WebSocketもサポートしている
Kaazing WebSocket Gateway Javaで作成されたWebSocketのゲートウェイ・サーバ
node.js サーバサイドで動作するJavaScriptコードのフレームワークでWebSocketもサポートしている
PHP Websocket Class PHPで作成されたWebSocketサーバ
SuperWebSocket .NETで作成されたWebSocketサーバ
WCF WebSockets WebSocket機能が拡張されたWCF
WebSocket対応のサーバ・プロダクト

 ほかにも多くのWebSocketサーバが出てきているが、上記のプロダクトがメジャーなものになる。今回はInsider.NET読者にとってなじみ深いであろうWCFベースのWebSocketサービス“WCF WebSockets”を使用してサンプルを構築する。

WebSocketで提供されるAPI

 実際にサンプルを作成する前に、WebSocketで提供されるAPIを確認しておこう。WebSocketオブジェクトは、以下のようなメンバを保有している。

メンバ 概要
WebSocket(url, protoclos) WebSocketオブジェクトを生成するコンストラクタ。どこに接続するかを第1パラメータに、同一アプリケーション内で用途によりプロトコルを分けて通信をしたい場合に任意の文字列を第2パラメータに指定する
send(data) WebSocketを利用してメッセージを送信する
close() WebSocketによる接続を切断する
onopen WebSocketによる接続が確立した際に呼び出されるイベント・ハンドラ
onclose WebSocketによる接続を切断した際に呼び出されるイベント・ハンドラ
onmessage WebSocketでメッセージを受信した際に呼び出されるイベント・ハンドラ
onerror WebSocketによるエラーが発生した際に呼び出されるイベント・ハンドラ
WebSocketが提供するAPI

 sendメソッドでは、現在の仕様では文字列のほかに、配列やBlobデータなども送信できる。

 WebSocketはサーバと接続する際に、「ws://」または「wss://」のどちらかから始まるURLを接続先として指定する。それぞれ違いは以下のとおり。

プロトコル 概要
ws:// WebSocketによる80ポートでの通信(「http://」に相当)。データは平文で送受信される
wss:// WebSocketによる443ポートでの通信(「https://」に相当)。データは暗号化して送受信される
WebSocketのプロトコル

 以上、WebSocketのAPIとプロトコルを押さえたところで、実際にサンプルを作成してみよう。


 INDEX
  [連載] 人気順に説明する初めてのHTML5開発
  双方向通信を実現! WebSocketを使いこなそう
  1.WebSocketとは?
    2.WebSocketでリアルタイム・チャット・アプリケーションを作る

インデックス・ページヘ  「連載:人気順に説明する初めてのHTML5開発」

更新履歴
【2011/11/14】

 以下のような誤りがありました。お詫びして訂正させていただきます。

以下の表はセキュリティ・ホールを解決したDraft(draft-ietf-hybi-thewebsocketprotocol-07)以降のDraft(=仕様の草案)に対応しているブラウザだ。現在、リリースされている主要ブラウザではChromeのみの実装となるが、2011年9月29日付で、WebApps Working Groupから、WebSocketの草案がラストコール(=最終勧告)として公開されている。
 以下の表はWebSocketプロトコルのラストコール(=最終勧告)となるDraft(draft-ietf-hybi-thewebsocketprotocol-07)以降のDraft(=仕様の草案)に対応しているブラウザだ。現在、リリースされている主要ブラウザではChromeとFirefoxのみの実装となるが、2011年9月29日付で、WebApps Working Groupから、WebSocket APIの草案もラストコールとして公開されている。
 なお、2011年11月の段階ではFirefoxでWebSocketを利用する際にWebSocketではなく、「MozWebSocket」と記載する必要がある。

Firefox: 未実装
Firefox: 6以降


【2011/11/21】

 以下のような誤りがありました。お詫びして訂正させていただきます。

追記 WebSocketプロトコルはラストコール以降も改訂が勧められ、2011年11月の段階でhybi-17まで改訂が進んでいる。

Firefox: 6以降
Firefox: 7以降


TechTargetジャパン

Insider.NET フォーラム 新着記事

@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

RSSフィード

キャリアアップ

.NET開発者中心に生まれ変わりました

.NET開発者中心コーナー

- PR -

@IT Sepcial

イベントカレンダー

PickUpイベント

- PR -
もっと見る
- PR -

お勧め求人情報

ホワイトペーパーTechTargetジャパン

@IT Sepcial
ソリューションFLASH