Web Socketsは、サーバとの双方向通信を実現するための非HTTP通信を、Webアプリケーションから行えるようにするための仕様である。HTTPでは実現が容易でなかった、サーバからのデータプッシュ等をスマートに実現するための技術として、非常に注目されている。
Web SocketsのAPI自体は非常に単純だ。サーバとの通信を確立するには、URL文字列をパラメータとしてWebSocketコンストラクタを呼び出すだけだ。
var ws = new WebSocket("ws://localhost:8005/echo");
URLは「ws」もしくは「wss」(暗号化通信時)というスキーマ文字列で始まる必要がある。設定したURLは、WebSocketオブジェクトのURLプロパティにアクセスすれば取得することができる。
通信を確立したら、サーバとの双方向通信が可能だ。サーバに対してデータを送信するにはsend()メソッドを使用する。送信出来るデータの型は文字列に限られる。
ws.send("data");
サーバからメッセージを受信するには、onmessageイベントハンドラを設定する。
ws.onmessage = function(event) {
var data = event.data;
...
};
通信の開始や終了を監視するためのイベントハンドラも存在する。
ws.onopen = function(event) {
// 通信開始時の処理
};
ws.onclose = function(event) {
// 通信終了時の処理
};
通信を切断するには、close()メソッドを使用する。
ws.close();
また、readyStateプロパティを読み取る事でWebSocketオブジェクトの状態を知ることができる。readyStateが取りうる値は以下の3つだ(括弧内の数値は定数の値)。
- CONNECTING(0) … 接続中
- OPEN(1) … 接続がオープンされた
- CLOSED(2) … 接続は閉じられている
以上が、Web SocketsのAPIのすべてである。
Web Socketsを試す
HTTPに縛られない、という可能性の広さとシンプルなAPIによって、大きな期待を抱かれているWeb Socketsであるが、残念ながら現時点ではWeb Socketsを実装したブラウザは存在しない。
ではWeb Socketsを試すことはできないのかというと、そうではない。「Kaazing Open Gateway」というプロダクトを利用すれば、現在でもWeb Socketsを試すことが可能だ(KaazingはHTTPを使用してWeb Socketsを実装しているので、あくまでも擬似的なものではある)。
そこで、ここではKaazing Open Gateway(以下Kaazing)をダウンロードしてサンプルを実行する方法を説明する。筆者はMac OS X 10.5.7上でサンプルの動作を確認した。その他のプラットフォームで試される方は、適宜読み替えながら手順を進めていただきたい。
Kaazingはこちらのページからダウンロードすることができる。原稿執筆時点のバージョンは「8.12_2 Battlestar」である。Web Socketsのデモを試すのが目的なので、ここでは30メガバイト超の「Demo Bundle」バージョンをダウンロードする。ダウンロードされたファイルはzip、もしくはtar.gzで圧縮されたファイルなので、任意の場所に展開する。
Kaazingを実行する前に、バージョン6以上のJavaがシステムにインストールされている必要がある。以下のコマンドを実行し、適切なバージョンのJavaがインストールされている事を確認していただきたい。
> java -version
java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57, mixed mode)
展開後のKaazingは、以下のようなディレクトリ構成になっているはずだ。
kaazing-gateway-demos-8.12_2-bin/ apache-activemq-5.1.0/ kaazing-gateway-8.12_2/
Kaazingを実行するためには、「kaazing-gateway-8.12_2/bin」ディレクトリ以下の「gateway.start」コマンドを実行する。
> ./gateway.start
INFO [Gateway] Starting server at 2009-07-24 14:03:20
INFO [Gateway] Starting services
INFO [Gateway] http://localhost:8000/
INFO [Gateway] http://localhost:8000/session
...(略)...
INFO [Gateway] Started management
INFO [Gateway] Started server successfully in 0.825 secs
起動に失敗してしまった場合は、Kaazingが使用するポート(8000-8005、9000-9005) を他のアプリケーションが占有していないか確認していただきたい。
起動したら、ブラウザから「http://localhost:8000/」にアクセスしてみよう。以下のような画面が表示されれば、Kaazingは無事実行されている。
echoデモの実行
今回ダウンロードしたバージョンのKaazingに含まれているデモの中で、Web Socketsを簡単に試すためには、「echo」というデモを試すとよい。これは、Web Socketsを使用してサーバに送信したメッセージが、そのままサーバから送り返されてくるという単純なものだ。
echoのデモ |
このサンプルを試すには、Kaazingを実行している状態で「http://localhost:8000/demo/echo.html」にアクセスすればよい……のだが、今回ダウンロードしたバージョンのKaazingにはバグがあり、正しく動作しない(Subversionでチェックアウトした最新のコードを見るとすでに修正されているので、次のバージョン以降は修正作業が必要ないだろう)。このデモを実行するには、「kaazing-gateway-8.12_2/conf/gateway-config.xml」と言う設定ファイル内を修正する必要がある。
同ファイルを開き、「Echo service」が定義されている箇所の「jabber」となっている部分を「echo」に書き換える必要がある。
<!-- Echo service -->
<service>
<!-- ws:// scheme refers to WebSocket -->
<!-- wss:// scheme refers to WebSocket (secure) -->
<!-- 以下のjabberをechoに書き換える -->
<accept>ws://localhost:8005/jabber</accept>
<accept>wss://localhost:9005/jabber</accept>
...(略)...
</service>
修正が完了したらKaazingを再起動して、「http://localhost:8000/demo/echo.html」にアクセスしていただきたい(ただし、Safari4でしか動作しなかった)。テキストフィールドにメッセージを入れて「Send」ボタンを押すと、サーバからメッセージがエコーされる事が確認できるはずだ。
このデモのソースコードを見ていただければ、Web SocketsのAPIを使用しただけの非常にシンプルなデモであることがおわかりいただけると思う。
// WebSocketの作成
websocket = new WebSocket(url.value);
// ソケットにメッセージが到着したら呼び出される
websocket.onmessage = function(evt) {
log("MESSAGE: " + evt.data);
}
// ソケットが閉じられたら呼び出される
websocket.onclosed = function(evt) {
log("DISCONNECTED");
}
connected = true;
// ソケットがオープンしたら呼び出される
websocket.onopen = function(evt) {
// サーバにメッセージを送信
// 標準仕様ではsend()だが、Kaazingは少し古い仕様をもとに実装されている
websocket.postMessage("123Test456");
};
ただし、Kaazingが準拠しているWeb Socketsの仕様が少し古いため、サーバにメッセージを送信するためのメソッドがsend()ではなくpostMessage()となっていることには注意が必要だ。
また、echoデモにおけるサーバサイドのソースコードに興味がある方は、Kaazingのソースコードを入手する必要がある。Subversionからソースコードをチェックアウト(svn co https://www.kaazing.org/svn)し、「svn/gateway/trunk/org.kaazing.gateway.server/src/main/java/org/kaazing/gateway/server/service/echo/EchoServiceHandler.java」を眺めてみるとよいだろう。