
シェア:
スティーブは自称数学者で、悪口の王様。グレイハウンド、曲がりくねったパズル、ヨーロッパのボードゲームをこよなく愛する。 非数学系の人には数学を、非Java系の人にはJavaの話をしていないときは、コーヒーを飲みながらコードをハックしている。
Spark FrameworkでWebSocketサーバーを作成する
ウェブソケットは、サーバーとブラウザー間の通信を可能にするプロトコルである。通信が双方向かつリアルタイムであるため、RESTful HTTPよりも優れている。このため、クライアントが定期的に更新をポーリングする代わりに、サーバーがいつでもクライアントに通知することができます。
この連載では、JavaでWebSocketサーバーを作成する3つの異なる方法を紹介します。 Spring Bootと Spark Frameworkそして Java API for WebSockets.
前提条件
使用するのは Gradleを使います。
さらに、JDKのコピーがインストールされていることを確認する必要がある。このチュートリアルではJDK 8を使用します。
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
SparkフレームワークによるWebSocket
スパークは、JavaやKotlinのウェブアプリケーションを作成するためのマイクロフレームワークである。
プロジェクトの作成
Gradleを使って新しいJavaアプリケーションを初期化します。以下のコマンドを使用してプロジェクト用のディレクトリを作成し、そのディレクトリに移動してアプリケーションを初期化します:
Spark の依存関係を追加する
以下の依存関係を dependenciesブロックに追加する。 build.gradle:
compile 'com.sparkjava:spark-core:2.7.2'とは異なる Spring BootでWebSocketサーバーを作るとは異なり、Sparkを使ったWebSocketは組み込みの Jettyサーバーでしか動作しないので、HTTPルートの前にパスとハンドラを定義する必要があります。
WebSocketハンドラの作成
WebSocketメッセージにはテキストとバイナリの両方があります。この両方のメッセージを処理できるハンドラを作成することになります。
という新しいクラスを作成する。 WebSocketHandlerという新しいクラスを作り @WebSocket:
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
@WebSocket
public class WebSocketHandler {
}が処理する各イベントは、アノテーションで定義される。 WebSocketHandlerアノテーションで定義されます。アノテーションは @OnWebSocketMessageアノテーションを使用して、バイナリまたはテキスト・イベントを受信するメソッドにタグを付けることができます。
デモンストレーションのために、受信したメッセージを送信者にエコーで返すエコー・サーバーを作成する。
以下のメソッドを追加する:
@OnWebSocketMessage
public void handleTextMessage(Session session, String message) throws IOException {
System.out.println("New Text Message Received");
session.getRemote().sendString(message);
}
@OnWebSocketMessage
public void handleBinaryMessage(Session session, byte[] buffer, int offset, int length) throws IOException {
System.out.println("New Binary Message Received");
session.getRemote().sendBytes(ByteBuffer.wrap(buffer));
}メソッド・シグネチャは、メソッドがどのタイプのメッセージを扱うかを決定することに注意してください。詳しくは OnWebSocketMessage注釈ドキュメントを参照してください。
WebSocketハンドラの登録
を使用するには WebSocketHandlerを使うには登録が必要です。
Gradleが作成した Appクラスを開いてください。メソッドと getGreetingメソッドと mainメソッドの内容を削除します。
メイン・メソッドの内部で、以下を追加して WebSocketHandlerを登録します。 /socketパスに登録します:
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
webSocket("/socket", WebSocketHandler.class);
} アプリケーションをテストするクライアントを作成する
WebSocketサーバーをテストするためにクライアントを作成する必要があります。テキスト・メッセージとバイナリ・メッセージの両方を送信するテストが必要です。これはJavaScriptで実現できます。
フォルダを resourcesフォルダーの中に src/mainフォルダーの中にフォルダの中に resourcesフォルダーの中に staticフォルダを作成する。
以下を index.htmlフォルダ内に src/main/resources/staticフォルダーの中に追加する:
<html>
<head>
<style>
#messages {
text-align: left;
width: 50%;
padding: 1em;
border: 1px solid black;
}
</style>
<title>Sample WebSocket Client</title>
</head>
<body>
<div class="container">
<div id="messages" class="messages"></div>
<div class="input-fields">
<p>Type a message and hit send:</p>
<input id="message"/>
<button id="send">Send</button>
<p>Select an image and hit send:</p>
<input type="file" id="file" accept="image/*"/>
<button id="sendImage">Send Image</button>
</div>
</div>
</body>
<script>
const messageWindow = document.getElementById("messages");
const sendButton = document.getElementById("send");
const messageInput = document.getElementById("message");
const fileInput = document.getElementById("file");
const sendImageButton = document.getElementById("sendImage");
const socket = new WebSocket("ws://localhost:8080/socket");
socket.binaryType = "arraybuffer";
socket.onopen = function (event) {
addMessageToWindow("Connected");
};
socket.onmessage = function (event) {
if (event.data instanceof ArrayBuffer) {
addMessageToWindow('Got Image:');
addImageToWindow(event.data);
} else {
addMessageToWindow(`Got Message: ${event.data}`);
}
};
sendButton.onclick = function (event) {
sendMessage(messageInput.value);
messageInput.value = "";
};
sendImageButton.onclick = function (event) {
let file = fileInput.files[0];
sendMessage(file);
fileInput.value = null;
};
function sendMessage(message) {
socket.send(message);
addMessageToWindow("Sent Message: " + message);
}
function addMessageToWindow(message) {
messageWindow.innerHTML += `<div>${message}</div>`
}
function addImageToWindow(image) {
let url = URL.createObjectURL(new Blob([image]));
messageWindow.innerHTML += `<img src="${url}"/>`
}
</script>
</html>
ここで、Sparkを設定して、アプリケーションの実行時に index.htmlを探し、アプリケーションの実行時にサーバーを初期化するように Spark を設定する必要があります。また、サーバーが接続をリッスンするポートを定義することもできる。
の mainクラスの Appクラスのメソッドの中に、以下を追加する。 webSocket:
staticFileLocation("static");
port(8080)
init(); アプリケーションの開始
これでWebSocketサーバーは完成です。アプリケーションのディレクトリ内で gradle runコマンドを使ってアプリケーションを起動します。
アプリケーションは以下からアクセスできます。 http://localhost:8080にアクセスしてください:
Connected
connected "メッセージは、JavaScriptクライアントが接続できたことを示す。
入力フィールドに入力して送信ボタンをクリックし、テキストメッセージを送信してみてください。また、画像をアップロードしてみてください。どちらの場合も、同じメッセージと画像がエコーバックされるはずです。
Connected Check
結論
このチュートリアルでは、バイナリーとテキストの両方のメッセージを受信できるWebSocketサーバーをSparkを使って作成する方法を学びました。このチュートリアルの完成したコードは リポジトリにあります。リポジトリにあります。
WebSocketを既存の スプリングアプリケーションに実装したいですか?もしかしたら Spring BootでWebSocketサーバーを作る?
フレームワークがない?問題ない!次回のチュートリアルでは、Java API for WebSocketsを使ってWebSocketサーバーを作成する方法を紹介します。
のエンドポイントとしてWebSocketを使用できることをご存知ですか? Nexmoコールコントロールオブジェクト?次の例を見てください。 Voice WebSocketを使ったブラウザへのストリーミングコール.
WebSocketsの面白い使い方を見たいですか?を見てみましょう。 nexmo-コミュニティ/dtmf-snakeレポジトリを見ると、デュアルトーンのマルチ周波数信号を使ってスネークゲームをすることができるコードを見ることができる。
