【Java】Java11でのWebSocketクライアント

Java11で利用できるjava.net.httpパッケージにWebSocketサーバーと通信できる機能が追加されたようなので今回はApache Tomcatを利用して本当にサーバーとWebSocket通信ができるのか試していきましょう。



使用するクラス群

HttpClient

WebSocketオブジェクトを作成するために使用するクラスです。
newWebSocketBuilderメソッドでWebSocketリクエスト用のオブジェクトを作成することができるWebSocket.Builderを作成できます。

WebSocket.Builder

WebSocketの設定を行いWebSocketオブジェクトを作成します。
buildAsyncメソッドで特定のURLにWebSocket接続要求を行います。

WebSocket

WebSocketのデータ送信、受信に関する処理を行います。
sendTextメソッドで文字列の送信処理を実行できます。
requestメソッドで受信データ数を増やせます。このメソッドで増分しておかないと、サーバからのデータを受信できません。
sendCloseメソッドで接続を閉じることができます。

WebSocket.Listener

WebSocketの接続イベント、受信イベントを取得するリスナです。
onOpenメソッドをオーバーライドして接続イベント、onTextメソッドをオーバーライドすると文字列受信イベントを処理できます。

WebSocket利用サンプル

ApacheTomcatサーバをWebSocketが使える状態で用意して試しに接続、メッセージ送信、切断をしてみます。

TestWSClient.java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;

public class TestWSClient {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		HttpClient client = HttpClient.newHttpClient();
		WebSocket.Builder wsb = client.newWebSocketBuilder();

		//WebSocketイベント
		WebSocket.Listener listener = new WebSocket.Listener() {
			@Override
			public void onOpen(WebSocket webSocket){
				System.out.println("接続しました。");

				//2回分のメッセージ受信を許容する
				webSocket.request(2);
			}
			@Override
			public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
				System.out.println("接続しました。");
				System.out.println(data);
				return null;
			}
		};

		//接続開始
		CompletableFuture<WebSocket> comp = wsb.buildAsync(URI.create("ws://127.0.0.1:8080/TestServer2/ws"), listener);

		//接続完了
		WebSocket ws = comp.get();

		//文字列送信
		ws.sendText("Hello World!!", true);

		Thread.sleep(1000);

		//切断
		CompletableFuture<WebSocket> end = ws.sendClose(WebSocket.NORMAL_CLOSURE, "なんとなく");

		//切断完了
		end.get();
	}

}

サーバー側のWebSocketクラスは下記の通りです。
このテストサーバーはeclipseのプロジェクトごとgitにアップロードしてます。

WebSocket.java
import java.io.IOException;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;


@ServerEndpoint("/ws")
public class WebSocket {
	Session sess;


    //接続確率
    @OnOpen
    public void onOpen(Session session) {
        /* セッション確立時の処理 */
        System.out.println("WebSocketセッション確立");
        sess = session;
    }

    //受信メッセージ
    @OnMessage
    public void onMessage(String message) {
        /* メッセージ受信時の処理 */
        System.out.println("WebSocket受信:" + message);
        try {
			//クライアントからメッセージを受け取ったら三回送信する
			sess.getBasicRemote().sendText("OK");
			sess.getBasicRemote().sendText("OK2");
			sess.getBasicRemote().sendText("OK3");
		} catch (IOException e) {
			e.printStackTrace();
		}
    }

    //エラー時
    @OnError
    public void onError(Throwable th) {
        /* エラー発生時の処理 */
        System.out.println("WebSocketエラー:" + th.getMessage());
    }

    //切断時
    @OnClose
    public void onClose(Session session) {
        /* セッション解放時の処理 */
        System.out.println("WebSocketセッション終了");
    }
}
クライアント側の実行結果

接続しました。
接続しました。
OK
接続しました。
OK2

サーバー側の実行結果

WebSocketセッション確立
WebSocket受信:Hello World!!
WebSocketセッション終了

サーバーから3回メッセージを送信してますが、requestメソッドで2を指定しているので、2回しか受信していませんね。
いちいちrequestメソッドを実行するのは面倒だな・・・

Java

Posted by nompor