WebSockets API用のJavaクライアント
1. 前書き
HTTP(Hypertext Transfer Protocol)は、ステートレスな要求/応答プロトコルです。 そのシンプルな設計により、非常にスケーラブルですが、すべての要求/応答とともに送信する必要があるオーバーヘッドの量のために、高度にインタラクティブなリアルタイムWebアプリケーションには不適切で非効率的です。
HTTPは同期的であり、リアルタイムアプリケーションは非同期である必要があるため、ポーリングやロングポーリング(Comet)などのソリューションは複雑で非効率的である傾向があります。
上記の問題を解決するには、サーバーとクライアントの両方で使用できる標準ベースの双方向全二重プロトコルが必要です。これにより、JSR 356 APIが導入されました。この記事では、使用例を示します。
2. セットアップ
SpringWebSocketの依存関係をプロジェクトに含めましょう。
org.springframework
spring-websocket
5.0.5.RELEASE
org.springframework
spring-messaging
5.0.5.RELEASE
spring-websocketおよびspring-messagingの依存関係の最新バージョンは、MavenCentralからいつでも取得できます。
3. ストンプ
ストリームテキスト指向メッセージングプロトコル(STOMP)は、クライアントとサーバーがほぼすべてのメッセージブローカーと通信できるようにする、シンプルで相互運用可能なワイヤー形式です。 AMQP(Advanced Message Queuing Protocol)およびJMS(Java Messaging Service)に代わるものです。
STOMPは、クライアント/サーバーがメッセージングセマンティクスを使用して通信するためのプロトコルを定義します。 セマンティクスはWebSocketの上にあり、WebSocketフレームにマッピングされるフレームを定義します。
STOMPを使用すると、さまざまなプログラミング言語でクライアントとサーバーを柔軟に開発できます。 この現在の例では、クライアントとサーバー間のメッセージングにSTOMPを使用します。
4. WebSocketサーバー
このarticleでWebSocketサーバーの構築について詳しく読むことができます。
5. WebSocketクライアント
WebSocketサーバーと通信するには、クライアントは、Upgradeヘッダーが適切に設定されたサーバーにHTTP要求を送信して、WebSocket接続を開始する必要があります。
GET ws://websocket.example.com/ HTTP/1.1
Origin: http://example.com
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket
WebSocketのURLはwsおよびwssスキームを使用し、2番目のURLは安全なWebSocketを意味することに注意してください。
WebSocketのサポートが有効になっている場合、サーバーは応答でUpgradeヘッダーを送信することで応答します。
HTTP/1.1 101 WebSocket Protocol Handshake
Date: Wed, 16 Oct 2013 10:07:34 GMT
Connection: Upgrade
Upgrade: WebSocket
このプロセス(WebSocketハンドシェイクとも呼ばれます)が完了すると、最初のHTTP接続は同じTCP / IP接続の上にあるWebSocket接続に置き換えられます。その後、いずれかの当事者がデータを共有できます。
このクライアント側の接続は、WebSocketStompClientインスタンスによって開始されます。
5.1. WebSocketStompClient
セクション3で説明したように、最初にWebSocket接続を確立する必要があります。これは、WebSocketClientクラスを使用して行われます。
WebSocketClientは、以下を使用して構成できます。
-
TyrusなどのJSR-356実装によって提供されるStandardWebSocketClient
-
Jetty9 +ネイティブWebSocketAPIによって提供されるJettyWebSocketClient
-
SpringのWebSocketClientの実装
この例では、WebSocketClientの実装であるStandardWebSocketClientを使用します。
WebSocketClient client = new StandardWebSocketClient();
WebSocketStompClient stompClient = new WebSocketStompClient(client);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
StompSessionHandler sessionHandler = new MyStompSessionHandler();
stompClient.connect(URL, sessionHandler);
new Scanner(System.in).nextLine(); // Don't close immediately.
デフォルトでは、WebSocketStompClientはSimpleMessageConverterをサポートします。 JSONメッセージを扱っているので、メッセージコンバーターをMappingJackson2MessageConverterに設定して、JSONペイロードをオブジェクトに変換します。
エンドポイントへの接続中に、afterConnectedやhandleFrameなどのイベントを処理するStompSessionHandlerのインスタンスを渡します。
サーバーでSockJがサポートされている場合は、StandardWebSocketClient.ではなくSockJsClientを使用するようにクライアントを変更できます。
5.2. StompSessionHandler
StompSessionを使用してWebSocketトピックをサブスクライブできます。 これは、StompSessionHandlerを実装するStompSessionHandlerAdapterのインスタンスを作成することで実行できます。
StompSessionHandlerは、STOMPセッションのライフサイクルイベントを提供します。 イベントには、セッションが確立されたときのコールバックと、失敗した場合の通知が含まれます。
WebSocketクライアントがエンドポイントに接続するとすぐに、StompSessionHandlerが通知され、afterConnected()メソッドが呼び出され、StompSessionを使用してトピックをサブスクライブします。
@Override
public void afterConnected(
StompSession session, StompHeaders connectedHeaders) {
session.subscribe("/topic/messages", this);
session.send("/app/chat", getSampleMessage());
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
Message msg = (Message) payload;
logger.info("Received : " + msg.getText()+ " from : " + msg.getFrom());
}
WebSocketサーバーが実行され、クライアントが実行されていることを確認してください。コンソールにメッセージが表示されます。
INFO o.b.w.client.MyStompSessionHandler - New session established : 53b993eb-7ad6-4470-dd80-c4cfdab7f2ba
INFO o.b.w.client.MyStompSessionHandler - Subscribed to /topic/messages
INFO o.b.w.client.MyStompSessionHandler - Message sent to websocket server
INFO o.b.w.client.MyStompSessionHandler - Received : Howdy!! from : Nicky
6. 結論
このクイックチュートリアルでは、SpringベースのWebSocketクライアントを実装しました。
完全な実装はover on GitHubで見つかります。