Jettyで始めるWebSocket超入門

第3回 サーバ側の実装(前編)

この記事を読むのに必要な時間:およそ 4 分

今回と次回を通して,WebSocketを使ったチャットアプリケーションのサーバ側の実装を解説します。

WebSocketプロトコル

サーバ側の実装を行なう前に,WebSocket APIを使うにあたり知っておいたほうが良いと思われるWebSocketプロトコルの仕様について簡単に説明します。

リビジョンについて

WebSocketはプロトコルもAPIもまだ策定中の仕様であり,リビジョンの違いにより問題が起こる可能性があります。最近の例では,リビジョン75と76では互換性がありません。両方のリビジョンに対応するため,片方の仕様で接続し失敗した時に他方で接続し直すサーバや,起動時にオプションでどちらを使用するのかを変更するサーバ等の実装があります。仕様策定中は特に,クライアントや中継サーバ等がどのリビジョンに対応しているかを考慮に入れ,サーバのライブラリのバージョン変更を行なう必要があります。

Jettyの対応状況については情報がほとんどありませんが,コード※1を確認すると接続要求のヘッダを見てリビジョン75と76で処理を切り換えている部分があります。しかし,リビジョン76で導入されたセキュリティ対策用の処理がなく,完全ではないようです。

※1)
興味のある方は,⁠org.eclipse.jetty.websocket.WebSocketServlet」をご覧ください。

中継機の対応

プロキシサーバやゲートウェイがWebSocketプロトコルに対応していない可能性があります。以前のドラフト版はHTTPとの親和性が高く,プロキシサーバやゲートウェイに何もしなくても通過しやすく,特にwssを使用しWebSocketプロトコル本体を隠蔽すればさほど問題になりませんでした。しかし,リビジョン76から接続確立の方法が変更になったため,プロキシサーバ等の対応が必要になる可能性が高くなりました。

接続の確立

連載第1回目でも説明しましたが,WebSocketプロトコルは接続の確立にHTTPを使用します。通常のHTTP接続であれば,要求→応答で接続が切断されますが,WebSocketではHTTP接続時に「Upgrade」というヘッダに「WebSocket」を指定し,プロトコルを切り換えることを通知します。プロトコルが切り替わると,HTTPのようには直ぐには切断せずに,接続状態を保ったまま双方向のデータ送信が可能になります。

ポート番号

ドラフト版のリビジョン35までは81番と815番となっていましたが,現行のリビジョンではHTTPと同様に「ws://」では80番を「wss://」では443番を使用することになっています。

バイナリ送信

WebSocketプロトコルはバイナリの送信にも対応する方向で策定が進んでいます。詳しくは「データ送信の詳細」の項で説明します。

WebSocketの詳細について

WebSocketプロトコルについて詳細を知りたい場合,IETFやWHATWGのサイトをご覧ください。IETFで公開されているドラフト版のWebSocketプロトコルは,当初はdraft-hixie-thewebsocketprotocolの名前で公開されていましたが,リビジョン76が公開された後に名称がdraft-ietf-hybi-thewebsocketprotocolに変更され,リビジョン番号もリセットされ00となったようです。今後はリビジョン番号だけではどのドラフトを指しているのか特定できず,混乱する可能性もあるため注意が必要です。また,WHATWGでは最新のリビジョンよりもさらに新しいドラフト版が公開されています。

作成するクラス

それでは,サーバ側の実装を行ないます。作成するクラスは次の3つです。

WebSocketChat
HTTPサーバとWebSocketサーバを設定します。HTTPサーバはJettyが準備しているクラスを使用し,WebSocketサーバには下記のMyWebSocketServletを使用します。
MyWebSocketServlet
JettyのWebSocketServletクラスを継承したクラスです。WebSocketの接続が発生した際に,下記のMyWebSocketをインスタンス化します。
MyWebSocket
JettyのWebSocketインターフェイスを実装したクラスです。WebSocketの接続別にインスタンス化されます。

実装はこの逆の順番で行ないます。

著者プロフィール

金城雄(きんじょうゆう)

NTTアドバンステクノロジ株式会社 アプリケーションソリューション事業本部 情報機器テクノロジセンタ所属。

Webテクノロジに関心を寄せるJavaScript好きのプログラマ。

コメント

コメントの記入