WebSocket を Java で。(サーバーもクライアントもJava) - WebSocket Java Server & Java Client



サンプルコードがきれいにまとまったページが無かったので作りました。

2022年6月追記
ちゃんと動くサンプルコードをGitHubに置きました．JavaScriptも試せます．

https://github.com/oyahiroki/hello-java-websocket


# サーバー側 WebSocket Java Server

```java:HelloEndPoint.java
package pkg;

import java.io.IOException;
import java.util.Set;

import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
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;

/**
 * Websocket Endpoint implementation class HelloEndPoint
 */

@ServerEndpoint("/helloendpoint")
public class HelloEndPoint {
	// 現在のセッションを記録
	Session currentSession = null;
	public HelloEndPoint() {
		super();
	}
	/* 接続がオープンしたとき */
	@OnOpen
	public void onOpen(Session session, EndpointConfig ec) {
		this.currentSession = session;
	}
	/* メッセージを受信したとき */
	@OnMessage
	public void receiveMessage(String msg) throws IOException {
		// メッセージをクライアントに送信する
		this.currentSession.getBasicRemote().sendText("Hello " + msg + ".");
		Set<Session> sessions = currentSession.getOpenSessions();
		for (Session session : sessions) {
			try {
				session.getBasicRemote().sendText("Hello " + msg + ".(2)");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/* 接続がクローズしたとき */
	@OnClose
	public void onClose(Session session, CloseReason reason) {
		// ...
	}
	/* 接続エラーが発生したとき */
	@OnError
	public void onError(Throwable t) {
		// ...
	}
}
```

# クライアント側 WebSocket Java Client

```java:WebSocketClientMain
package pkg;

import java.net.URI;

import javax.websocket.ClientEndpoint;
import javax.websocket.ContainerProvider;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

/**
 * Websocket Endpoint implementation class WebSocketClientMain
 */

@ClientEndpoint
public class WebSocketClientMain {

	public WebSocketClientMain() {
		super();
	}

	@OnOpen
	public void onOpen(Session session) {
		/* セッション確立時の処理 */
		System.err.println("[セッション確立]");
	}

	@OnMessage
	public void onMessage(String message) {
		/* メッセージ受信時の処理 */
		System.err.println("[受信]:" + message);
	}

	@OnError
	public void onError(Throwable th) {
		/* エラー発生時の処理 */
	}

	@OnClose
	public void onClose(Session session) {
		/* セッション解放時の処理 */
	}

	static public void main(String[] args) throws Exception {

		// 初期化のため WebSocket コンテナのオブジェクトを取得する
		WebSocketContainer container = ContainerProvider
				.getWebSocketContainer();
		// サーバー・エンドポイントの URI
		URI uri = URI
				.create("ws://localhost:9080/hellowebsocket/helloendpoint");
		// サーバー・エンドポイントとのセッションを確立する
		Session session = container.connectToServer(new WebSocketClientMain(),
				uri);

		session.getBasicRemote().sendText("こんにちは");

		while (session.isOpen()) {
			Thread.sleep(100 * 1000);
			System.err.println("open");
		}

	}

}
```

# WebSocket Java 11 Client

## 補足

Java11 ではネイティブでWebSocket Clientをサポートしているとのことです．

```java
package hello.java11;

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 HelloWebServiceClient {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		String url = "ws://localhost:8080/hello-websocket/helloendpoint";
		HttpClient client = HttpClient.newHttpClient();
		WebSocket.Builder wsb = client.newWebSocketBuilder();
		// The receiving interface of WebSocket
		WebSocket.Listener listener = new WebSocket.Listener() {
			// A WebSocket has been connected.
			@Override
			public void onOpen(WebSocket webSocket) {
				System.out.println("onOpen");
				// Increments the counter of invocations of receive methods.
				webSocket.request(10);
			}
			// A textual data has been received.
			@Override
			public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
				System.out.println("onText");
				System.out.println(data);
				return null;
			}
		};
		// Builds a WebSocket connected to the given URI and associated with the given
		// Listener.
		CompletableFuture<WebSocket> comp = wsb.buildAsync( //
				URI.create(url) //
				, listener);
		// Waits if necessary for this future to complete, and then returns its result.
		WebSocket ws = comp.get();
		// Sends textual data with characters from the given character sequence.
		ws.sendText("Hello.", true);
		Thread.sleep(1000);
		// Initiates an orderly closure of this WebSocket's output by sending
		// a Close message with the given status code and the reason.
		CompletableFuture<WebSocket> end = ws.sendClose(WebSocket.NORMAL_CLOSURE, "CLOSURE");
		// Waits if necessary for this future to complete, and then returns its result.
		end.get();
	}
}


```




# maven
https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api/1.1

```xml
<!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api -->
<dependency>
    <groupId>javax.websocket</groupId>
    <artifactId>javax.websocket-api</artifactId>
    <version>1.1</version>
    <scope>provided</scope>
</dependency>
```

# おまけ JavaScriptのクライアント WebSocket JavaScript Client

```javascript
var connection;
function print(msg) {
	$("#msg").append($("#msg").val() + "\n" + msg);
}
$(function() {
	console.log("hello");
	//WebSocket接続
	connection = new WebSocket(
			"ws://localhost:8080/hello-websocket/helloendpoint");
	//接続通知
	connection.onopen = function(event) {
		console.log("open");
		console.log(event);
		print("open");
	};
	//エラー発生
	connection.onerror = function(event) {
		console.log("onerror");
		console.log(event);
		print("onerror");
	};
	//メッセージ受信
	connection.onmessage = function(event) {
		console.log("onmessage");
		console.log(event);
		print("onmessage");
		print(event.data);
		//			document.getElementById("dispMsg").value = event.data;
	};
	//切断
	connection.onclose = function() {
		console.log("onclose");
		print("onclose");
	};
	
	$("#btn1").on("click",function(){
		connection.send("hi");
	});
});
```


# 参考にしたページ

## WebSocket Server (Java)

「WebSphere Application Server Liberty Core」で新たに正式サポートされたWebSocketを使ってみた (1/6)：CodeZine（コードジン）
https://codezine.jp/article/detail/8418


## WebSocket Client (Java)

WebSocket のクライアントを作ってみた (Java で) (クレスコエンジニアブログ)
http://service.cresco.co.jp/blog/entry/184