SpringによるWebSocketsの紹介
1概要
この記事では、Spring Framework 4.0で導入された
新しいWebSocket機能
を使用してメッセージングを実装する簡単なWebアプリケーションを作成します。
WebSocketsは、Webブラウザとサーバー間の
双方向
、
全二重
、
永続的接続
です。 WebSocket接続が確立されると、クライアントまたはサーバーがこの接続を閉じることを決定するまで、接続は開いたままになります。
典型的なユースケースは、チャットのように、アプリが互いに通信する複数のユーザーを含む場合です。
2 Mavenの依存関係
これはMavenベースのプロジェクトなので、まず
pom.xml
に必要な依存関係を追加します。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
さらに、メッセージの本文を作成するために
JSON
を使用するので、
Jackson
依存関係を追加する必要があります。これにより、SpringはJavaオブジェクトを
JSON
との間で変換します。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.3</version>
</dependency>
上記のライブラリの最新版を入手したい場合は、https://search.maven.org/classic/[Maven Central]でそれらを探してください。
3 Spring
でWebSocketを有効にする
最初にすべきことは、WebSocket機能を有効にすることです。これを行うには、アプリケーションに設定を追加し、このクラスに
@ EnableWebSocketMessageBroker
というアノテーションを付ける必要があります。
その名前が示すように、メッセージブローカーに支えられてWebSocketメッセージ処理を有効にします。
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat");
registry.addEndpoint("/chat").withSockJS();
}
}
メソッド
configureMessageBroker
は、メッセージブローカーを設定するために使用されます。まず、インメモリのメッセージブローカーが「/topic」という接頭辞を付けた宛先でクライアントにメッセージを戻すことができます。
アプリケーションのアノテーション付きメソッドをターゲットとする宛先をフィルタリングするために“/app”プレフィックスを指定することでW設定(
@ MessageMapping
を介して)
registerStompEndpoints
メソッドは“/chat”エンドポイントを登録し、
Springのhttp://stomp.github.io/stomp-specification-1.2.html#Abstract[STOMP]サポート
を有効にします。弾力性のためにSockJSなしで動作するエンドポイントもここに追加していることに注意してください。
このエンドポイントは、「/app」というプレフィックスが付いている場合、
ChatController.send()
メソッドが処理するようにマッピングされているエンドポイントです。
また、
SockJS
フォールバックオプションを有効にします
ので、WebSocketが利用できない場合は別のメッセージングオプションを使用できます。 WebSocketはまだすべてのブラウザでサポートされているわけではなく、制限的なネットワークプロキシによって除外される可能性があるため、これは便利です。
このフォールバックにより、アプリケーションはWebSocket APIを使用できるようになりますが、実行時に必要に応じてWebSocket以外の代替方法に段階的に低下します。
4メッセージモデルを作成する
プロジェクトを設定してWebSocket機能を設定したので、送信するメッセージを作成する必要があります。
エンドポイントは、本文が
JSON
オブジェクトであるSTOMPメッセージ内の送信者名とテキストを含むメッセージを受け入れます。
メッセージは次のようになります。
{
"from": "John",
"text": "Hello!"
}
テキストを伝えるメッセージをモデル化するために、
from
および
text
プロパティを持つ単純な____ Javaオブジェクトを作成できます。
public class Message {
private String from;
private String text;
//getters and setters
}
デフォルトでは、Springは
Jackson
ライブラリを使用してモデルオブジェクトをJSONとの間で変換します。
5メッセージ処理コントローラを作成する
これまで見てきたように、STOMPメッセージングを扱うためのSpringのアプローチは、設定されたエンドポイントにコントローラメソッドを関連付けることです。これは
@ MessageMapping
アノテーションによって可能になります。
エンドポイントとコントローラ間の関連付けにより、必要に応じてメッセージを処理することができます。
@MessageMapping("/chat")
@SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
String time = new SimpleDateFormat("HH:mm").format(new Date());
return new OutputMessage(message.getFrom(), message.getText(), time);
}
F.オブジェクトに送信者と受信メッセージから取得したメッセージテキストを入力し、タイムスタンプを付加します。
メッセージを処理した後、
@ SendTo
アノテーションで定義された適切な宛先に送信します。 “
/topic/messages
”宛先へのすべての購読者はメッセージを受け取ります。
6. ブラウザクライアントを作成する
サーバーサイドで設定を行った後は、
sockjs-client
ライブラリ
を使用して、メッセージングシステムと対話する簡単なHTMLページを作成します。
まず、
sockjs
および
stomp
Javascriptクライアントライブラリをインポートする必要があります。次に、エンドポイントとの通信を開くための
connect()
関数、STOMPメッセージを送信するための
sendMessage()
関数、および通信を閉じるための
disconnect()
関数を作成します。
<html>
<head>
<title>Chat WebSocket</title>
<script src="./js/sockjs-0.3.4.js"></script>
<script src="./js/stomp.js"></script>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility
= connected ? 'visible' : 'hidden';
document.getElementById('response').innerHTML = '';
}
function connect() {
var socket = new SockJS('/spring-mvc-java/chat');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/messages', function(messageOutput) {
showMessageOutput(JSON.parse(messageOutput.body));
});
});
}
function disconnect() {
if(stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendMessage() {
var from = document.getElementById('from').value;
var text = document.getElementById('text').value;
stompClient.send("/app/chat", {},
JSON.stringify({'from':from, 'text':text}));
}
function showMessageOutput(messageOutput) {
var response = document.getElementById('response');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(messageOutput.from + ": "
+ messageOutput.text + " (" + messageOutput.time + ")"));
response.appendChild(p);
}
</script>
</head>
<body onload="disconnect()">
<div>
<div>
<input type="text" id="from" placeholder="Choose a nickname"/>
</div>
<br/>
<div>
<button id="connect" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">
Disconnect
</button>
</div>
<br/>
<div id="conversationDiv">
<input type="text" id="text" placeholder="Write a message..."/>
<button id="sendMessage" onclick="sendMessage();">Send</button>
<p id="response"></p>
</div>
</div>
</body>
</html>
** 7. 例のテスト
**
この例をテストするために、ブラウザウィンドウをいくつか開いてチャットページにアクセスします。
http://localhost:8080/spring-mvc-java/resources/chat.html
リンク:/uploads/screenshot.png[]
8結論
このチュートリアルでは、SpringのWebSocketをサポートします。サーバーサイドの設定を見て、
sockjs
と
stomp
JavaScriptライブラリを使って簡単なクライアントサイドを構築しました。
サンプルコードはhttps://github.com/eugenp/tutorials/tree/master/spring-mvc-java[GitHubプロジェクト]にあります。