第 14 章 JAKARTA WEBSOCKET アプリケーションの作成
Jakarta WebSocket プロトコルは、Web クライアントとサーバー間の双方向通信を提供します。クライ
アントとサーバー間の通信はイベントベースであるため、ポーリングベースの通信よりも処理が高速に なり、帯域幅が小さくなります。Jakarta WebSocket は、JavaScript API を用いて Web アプリケー ションで使用したり、Jakarta Websocket 仕様を用いてクライアント Jakarta WebSocket エンドポイン トで使用したりできます。
最初に接続はクライアントとサーバー間で HTTP 接続として確立されます。その後、クライアントは Upgrade ヘッダーを使用して Jakarta WebSocket 接続を要求します。同じ TCP/IP 接続上ではすべて 全二重通信になり、データのオーバヘッドが最小化されます。各メッセージには不必要な HTTP ヘッ ダーコンテンツが含まれていないため、Jakarta WebSocket 通信で必要な帯域幅は小さくなります。そ の結果、通信パスのレイテンシーが低くなるため、リアルタイムの応答が必要なアプリケーションに適 しています。
JBoss EAP Jakarta WebSocket 実装は、サーバーエンドポイントに対して完全な依存関係注入サポート
を提供しますが、クライアントエンドポイントに対して Contexts and Dependency Injection サービス を提供しません。
Jakarta WebSocket アプリケーションには以下のコンポーネントと設定変更が必要です。
Java クライアントまたは Jakarta WebSocket が有効になっている HTML クライアント。
HTML クライアントのブラウザーサポートは、http://caniuse.com/#feat=websockets を参照 してください。
Jakarta WebSocket サーバーエンドポイントクラス。
Jakarta WebSocket API で依存関係を宣言するために設定されたプロジェクト依存関係。
Jakarta WebSocket アプリケーションの作成
以下のコード例は、JBoss EAP に同梱される websocket-hello クイックスタートの一部です。これ は、接続を開き、メッセージを送信し、接続を閉じる Jakarta WebSocket アプリケーションの単純な例 です。他の機能を実装したり、実際のアプリケーションで必要となるエラー処理を含むことはありませ ん。
1. JavaScript HTML クライアントを作成します。
以下は Jakarta WebSocket クライアントの例になります。この例には 3 つの JavaScript 関数 が含まれています。
connect(): この関数は、Jakarta WebSocket URI を渡す Jakarta WebSocket 接続を作成し ます。リソースの場所は、サーバーエンドポイントクラスに定義されたリソースと一致し ます。この関数は、Jakarta WebSocket の onopen、onmessage、onerror、および
onclose もインターセプトし、処理します。
sendMessage(): この関数はフォームに入力された名前を取得し、メッセージを作成しま
す。さらに、WebSocket.send() コマンドを使用してメッセージを送信します。
disconnect(): この関数は WebSocket.close() コマンドを実行します。
displayMessage(): この関数は、ページ上の表示メッセージを Jakarta WebSocket エンド ポイントメソッドによって返された値に設定します。
displayStatus(): この関数は Jakarta WebSocket の接続状態を表示します。
例
例
:アプリケーション アプリケーション
index.htmlコード コード
<html>
<head>
<title>WebSocket: Say Hello</title>
<link rel="stylesheet" type="text/css" href="resources/css/hello.css" />
<script type="text/javascript">
var websocket = null;
function connect() {
var wsURI = 'ws://' + window.location.host + '/websocket-hello/websocket/helloName';
websocket = new WebSocket(wsURI);
websocket.onopen = function() { displayStatus('Open');
document.getElementById('sayHello').disabled = false;
displayMessage('Connection is now open. Type a name and click Say Hello to send a message.');
};
websocket.onmessage = function(event) { // log the event
displayMessage('The response was received! ' + event.data, 'success');
};
websocket.onerror = function(event) { // log the event
displayMessage('Error! ' + event.data, 'error');
};
websocket.onclose = function() { displayStatus('Closed');
displayMessage('The connection was closed or timed out. Please click the Open Connection button to reconnect.');
document.getElementById('sayHello').disabled = true;
};
}
function disconnect() { if (websocket !== null) { websocket.close();
websocket = null;
}
message.setAttribute("class", "message");
message.value = 'WebSocket closed.';
// log the event }
function sendMessage() { if (websocket !== null) {
var content = document.getElementById('name').value;
websocket.send(content);
} else {
displayMessage('WebSocket connection is not established. Please click the Open Connection button.', 'error');
} }
function displayMessage(data, style) {
var message = document.getElementById('hellomessage');
message.setAttribute("class", style);
message.value = data;
}
function displayStatus(status) {
var currentStatus = document.getElementById('currentstatus');
2. Jakarta WebSocket サーバーエンドポイントを作成します。
以下の方法のいずれかを使用して Jakarta WebSocket サーバーエンドポイントを作成できま す。
Programmatic Endpoint: エンドポイントは Endpoint クラスを拡張します。
Annotated Endpoint: エンドポイントクラスはアノテーションを使用して Jakarta
WebSocket イベントと対話します。これは、プログラム的なエンドポイントよりも簡単に
コーディングできます。
以下のコード例では、アノテーション付きエンドポイントが使用され、以下のイベントが処理 されます。
@ServerEndpoint アノテーションは、このクラスを Jakarta WebSocket サーバーエンド ポイントとして識別し、パスを指定します。
Jakarta WebSocket 接続が開かれると @OnOpen アノテーションがトリガーされます。
メッセージが受信されると、@OnMessage アノテーションがトリガーされます。
currentStatus.value = status;
} </script>
</head>
<body>
<div>
<h1>Welcome to Red Hat JBoss Enterprise Application Platform!</h1>
<div>This is a simple example of a Jakarta WebSocket implementation.</div>
<div id="connect-container">
<div>
<fieldset>
<legend>Connect or disconnect using websocket :</legend>
<input type="button" id="connect" onclick="connect();" value="Open Connection"
/>
<input type="button" id="disconnect" onclick="disconnect();" value="Close Connection" />
</fieldset>
</div>
<div>
<fieldset>
<legend>Type your name below, then click the `Say Hello` button :</legend>
<input id="name" type="text" size="40" style="width: 40%"/>
<input type="button" id="sayHello" onclick="sendMessage();" value="Say Hello"
disabled="disabled"/>
</fieldset>
</div>
<div>Current WebSocket Connection Status: <output id="currentstatus"
class="message">Closed</output></div>
<div>
<output id="hellomessage" />
</div>
</div>
</div>
</body>
</html>
Jakarta WebSocket 接続が閉じられると @OnClose アノテーションがトリガーされます。
例:
例:
Jakarta WebSocketエンドポイントコード エンドポイントコード
3. プロジェクト POM ファイルで Jakarta WebSocket API の依存関係を宣言します。
Maven を使用する場合は、プロジェクト pom.xml ファイルに以下の依存関係を追加します。
例
例
: Maven依存関係 依存関係
JBoss EAP に同梱されるクイックスタートには、追加の Jakarta WebSocket クライアントとエンドポ
イントのコード例が含まれます。
package org.jboss.as.quickstarts.websocket_hello;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/websocket/helloName") public class HelloName {
@OnMessage
public String sayHello(String name) {
System.out.println("Say hello to '" + name + "'");
return ("Hello" + name);
}
@OnOpen
public void helloOnOpen(Session session) {
System.out.println("WebSocket opened: " + session.getId());
}
@OnClose
public void helloOnClose(CloseReason reason) {
System.out.println("WebSocket connection closed with CloseCode: " + reason.getCloseCode());
} }
<dependency>
<groupId>org.jboss.spec.javax.websocket</groupId>
<artifactId>jboss-websocket-api_1.1_spec</artifactId>
<scope>provided</scope>
</dependency>