https://blogs.oracle.com/arungupta/entry/websocket_applications_using_java_jsr
WebSocketは一つのTCP接続で全二重、双方向の通信を提供するプロトコルです。JSR 356はJava EE 7プラットフォームでWebSocketアプリケーションを作るための標準APIを定義しています。
JSR 356: JavaTM API for WebSocketこのTip Of The Day (TOTD)では、WebSocketの概要と、JSRがどのように進化してプログラミングモデルをサポートするようになっているかをお伝えします。
http://jcp.org/en/jsr/detail?id=356
まず、WebSocketの入門編から。
WebSocketとは、IETF RFC 6455 Protocol と W3C JavaScript API (still a Candidate Recommendation)を組み合わせたものです。このプロトコルは定義します ハンドシェイクとデータ転送の開通を定義します。APIを使って、WebページがWebSocketプロトコルによりリモートホストと双方向の通信が可能です。
The WebSocket ProtocolHTTPとは異なり、新たなTCP接続を作成する必要はありません。クライアントとサーバ間の各メッセージ交換のためにぎっしり詰め込んだヘッダーを送信する必要もありません。WebSocketプロトコルはTCP上の基本的なメッセージフレームを定義しています。最初のハンドシェイクがHTTP Upgradeを使って成立すると、他から独立してクライアントとサーバはお互いにメッセージを送信できます。リクエスト/レスポンスやクライアント・サーバ間の一方向の事前定義されたメッセージ交換パターンはなく、これらを基本的なプロトコル上で明示的に定義する必要があります。
http://tools.ietf.org/html/rfc6455
The WebSocket API
http://www.w3.org/TR/websockets/
Upgrade Headerクライアントとサーバの間の通信はかなり対称的ですが、2つの違いがあります。
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.42
- クライアントはWebSocketリクエストを待つサーバへの接続を開始する
- クライアントはURIを使ってサーバに接続する。サーバは複数のクライアントからのリクエストを同じURIで待ち受けることができる。
ハンドシェイクに成功すると、クライアントとサーバはデータを「メッセージ」と呼ばれる概念的な単位で送受信します。メッセージは1個以上のフレームからなります。アプリケーションフレームにはアプリケーション用のペイロードが載っており、テキストデータもしくはバイナリデータの可能性があります。コントロールフレームにはプロトコルレベルの信号伝達のためのデータが載っています。
ではJSRについて説明しましょう。
Java Community ProcessでJSR 356としてJava API for WebSocketに取り組んでいます。ここではWebSocketアプリケーションを構築するための標準APIを定義します。このJSRは以下のようなサポートを提供します。
- 双方向WebSocketの会話を処理するWebSocket Javaコンポーネントの作成
- WebSocketイベントの開始、インターセプト
- WebSocketのテキスト/バイナリメッセージの作成と利用
- アプリケーションのためのWebSocketプロトコルとコンテンツモデルの定義機能
- WebSocketセッションの構成および管理(タイムアウト、リトライ、クッキー、接続プーリングなど)
- WebSocketアプリケーションがJava EEセキュリティモデル内で動作するための仕様
JSR 356: JavaTM API for WebSocketでは最後にコードをいくつか。
http://www.jcp.org/en/jsr/detail?id=356
Java API for WebSocket
http://java.net/projects/websocket-spec/
Tyrus
http://tyrus.java.net/
GlassFish 4.0 (Promoted Build)
http://dlc.sun.com.edgesuite.net/glassfish/4.0/promoted/
APIを使ってアノテーションやインターフェースを使いWebSocketエンドポイントを作成できます。このTOTDではアノテーションを使った簡単なサンプルをご紹介しましょう。将来のエントリでより進んだサンプルをご紹介する予定です。
@WebSocketEndpoint
と@WebSocketMessage
を使ってPOJOをWebSocketエンドポイントに変換することができます。@WebSocketEndpoint(path="/hello") public class HelloBean { @WebSocketMessage public String sayHello(String name) { return "Hello " + name + "!"; } }
@WebSocketEndpoint
はこのクラスをpath
属性で定義されたURIを待ち受けるWebSocketエンドポイントとしてマークします。
@WebSocketMessage
はインバウンドのWebSocketメッセージを受信するメソッドを識別します。この最初のメソッドパラメータをインバウンドメッセージのペイロードに注入します。この場合、ペイロードはテキストベースを仮定しています。ペイロードがバイナリの場合、byte[]
型を取ることができます。@WebSocketEndpoint
でdecoders
属性を指定している場合、カスタムオブジェクトを指定できます。この属性はカスタムオブジェクトをデコードする方法を定義するクラスのリストを提供します。- このメソッドはオプションで
Session
パラメータを取ることもできます。これはランタイムによって注入され、2個のエンドポイント間の会話をキャプチャします。 - メソッドの返値の型は
String
やbyte[]
、その他カスタムオブジェクトの型を取ることができます。@WebSocketEndpoint
のencoders
属性はカスタムオブジェクトをエンコードする方法を定義するために必要です。
index.jsp
です。JSPの本体は以下のようになっています。コードは比較的単純です。HTMLフォームには
nameField
.というテキストフィールドとボタンがあり、そのボタンから say_hello()
メソッドを呼び出します。div
プレースホルダは、出力表示に利用できます。では、JavaScriptコードを見てみましょう。
<script language="javascript" type="text/javascript"> var wsUri = "ws://localhost:8080/HelloWebSocket/hello"; var websocket = new WebSocket(wsUri); websocket.onopen = function(evt) { onOpen(evt) }; websocket.onmessage = function(evt) { onMessage(evt) }; websocket.onerror = function(evt) { onError(evt) }; function init() { output = document.getElementById("output"); } function say_hello() { websocket.send(nameField.value); writeToScreen("SENT: " + nameField.value); }
- このアプリケーションは、GlassFish 4.0 promoted build 57に "HelloWebSocket.war"(ダウンロードはこちら)としてデプロイされるので、WebSocketのエンドポイントは、"ws://localhost:8080/HelloWebSocket/hello"で待ち受けています。接続するためにURIを指定して、新しいWebSocket接続を開始します。
- JavaScript APIはコールバックメソッドを定義しています。このコールバックメソッドは、接続が開通 (
onOpen
)したり、閉塞 (onClose
)したり、エラーを受信(onError
)したり、エンドポイントからメッセージを受信 (onMessage
)したりしたときに呼び出されます。
- クライアントAPIにはデータ送信のための様々な
send
メソッドがあります。このスクリプトは、say_hello
メソッドで先ほどご紹介したHTMLのnameField
の値を使い、テキストデータを送信します。 - ボタンをクリックする都度、WebSocket接続を介してエンドポイントにテキストボックスの内容を送信し、上記
sayHello
メソッドに基づいた応答を受信します。
- こちらからソースもしくはWARファイルをダウンロードする
- GlassFish4.0 build 57、それ以後をダウンロードして展開する
- "asadmin start-domain"でGlassFishを起動する
- "asadmin deploy HelloWebSocket.war"でWARファイルをデプロイする
- http://localhost:8080/HelloWebSocket/index.jspからアプリケーションにアクセス
以下は参考資料です。
- WebSocket - Protocol and JavaScript API
- JSR 356: Java API for WebSocket - 仕様 (早期ドラフト) と実装 (既にGlassFish 4 promoted buildに統合されています)
- ペイロードにバイナリデータを載せる場合
- エンコーダ/デコーダを使うカスタムペイロード
- エラー処理
- インターフェースドリブンのWebSocketエンドポイント
- Java client API
- クライアントとサーバの設定
- セキュリティ
- サブプロトコル
- 拡張機能
- APIからのその他のトピック
- 流れているWebSocketメッセージをキャプチャする
0 件のコメント:
コメントを投稿