Java WebSocketとは
WebSocketとは、Webでの双方向通信を低コストで行うための仕組みのことです。
Web通信には、主に「HTTP」が使われていました。
HTTPは、HTMLで記述された文書を転送するためのプロトコルで、この規格が定められた当時のWebページは、遠くにいる人たち同士が知識・情報を共有するために作られました。
しかし、Webの発展にあわせてSNSをはじめとするインタラクティブ(対話型・双方向)なWebアプリケーションの登場によって、リアルタイムでのやりとりが必要になっています。
例えば、TwitterやFacebookなど誰かが投稿した内容が、他の人の画面でもリアルタイムに表示・更新されないと困りますよね。
この、リアルタイムなやりとり(双方向通信)を実現するのに、HTTPでは少し難しかったのです。
- 1つのコネクションで1つのリクエストしか送れない
- リクエストはクライアントからしか送れない
- ヘッダーが冗長(情報量が多い)
それでもなんとかして、HTTPを用いてクライアント⇄サーバ間の双方向通信ができるよう取り組んでいました。
例えば、一定の間隔でクライアントがサーバに問い合わせをし続けるロングポーリングや、Cometという手法などです。
通信を開始するサーバプッシュ機能をサーバ側からできるよう、疑似的に実現していました。
とは言えやはり無駄が多く、HTTPのボトルネックが解決されることはありませんでした。
そこで登場したのがWebSocketという新しいプロトコルです。
WebSockeは、サーバとクライアントがコネクションを確立(ハンドシェイク)できると、その後の通信を専用プロトコル(双方向通信)で行ってくれます。
- ハンドシェイク:HTTP通信によって実現します
- 双方向通信:送信データを「フレーム」単位で扱う
WebSockeには、サーバプッシュ機能が備わっており、サーバとクライアントの双方向で通信可能です。
また、ヘッダのサイズが最小2byte、最大14byteと小さいため、通信量の削減にもなります。
Java WebSocketのサンプル
では、JavaでWebSocketのサンプルを見ていきましょう。
各種実装方法は、下記の通りです。
- WebSocket Server:Java
- WebSocket Client:JavaScript
このサンプルでは、クライアント側から送信するメッセージをサーバが受信し、サーバからクライアントへメッセージを返すところまでを実装します。
開発環境にはEclipseを使用します。
開発環境の設定については、下記の記事が参考になると思うので必要な方はチェックしてみてください。
【関連記事】
▶︎【Java】Webアプリケーションとは?開発環境の設定からサンプルコードまで紹介!
WebSocket Serverを作成
まずは、WebSocket Serverを作成しましょう。
Eclipseを起動して、パッケージエクスプローラーから「新規」>「Java プロジェクト」を作成しましょう。
プロジェクト名は「SampleServer」としました。
作成したプロジェクトの中に「WebSocketServer.java」というJavaファイルを作成しましょう。
ディレクトリ構成は下記の画像のようになっていればOKです。
WebSocketServer.java には下記のように記述します。
■記述例 package main.java; 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("/WebSocketServer") public class WebSocketServer { @OnMessage public String onMessage(String message) { // メッセージを受信した際の処理を実装 System.out.println("WebSocketで受信したメッセージ:" + message); return "WebSocketでメッセージを正常に受信しました!"; } @OnError public void onError(Throwable th) { // WebSocketエラーが発生した際の処理を実装 System.out.println("WebSocketエラーが発生:" + th.getMessage()); } @OnOpen public void onOpen(Session session) { // セッションが確立した際の処理を実装 System.out.println("WebSocketセッション確立"); } @OnClose public void onClose(Session session) { // セッションを終了する際の処理を実装 System.out.println("WebSocketセッション終了"); } }
import文で使用するライブラリをインポートしています。
- OnClose:このメソッドレベルのアノテーションは、Web ソケットセッションが閉じているときに呼び出される Java メソッドを修飾するために使用できます。
- OnError:のメソッドレベルのアノテーションを使用して、エラーを処理するために呼び出す Java メソッドを修飾できます。
- OnMessage:このメソッドレベルのアノテーションを使用して、Java メソッドに受信 Web ソケットメッセージを受信させることができます。
- OnOpen:このメソッドレベルのアノテーションを使用して、新しい Web ソケットセッションが開いているときに呼び出される Java メソッドを修飾できます。
- Session:Web ソケットセッションは、2 つの Web ソケットエンドポイント間の会話を表します。
- ServerEndpoint:
このクラスレベルのアノテーションは、それが装飾するクラスが、Web ソケットサーバーの URI 空間でデプロイおよび利用可能になる Web ソケットエンドポイントであることを宣言します。
参考:パッケージ javax.websocket
参考:パッケージ javax.websocket.server
WebSocket Server がクライアントからデータを受け取るために、@ServerEndpointというアノテーションとエンドポイントを指定します。
【関連記事】
▶︎Javaのアノテーションって何?仕組みと基本的な使い方を解説
これによって、WebSocket Client が該当するJavaファイルを見つけられるようになるのです。
websocketクラスのアノテーションを利用して、以下の処理を実装します。
- メッセージを受信した際の処理
- エラーが発生した際の処理
- セッションを確立した際の処理
- セッションを終了した際の処理
それぞれの処理はコードに書かれている通りで、セッションを確立した際は確立した旨を表示させています。
WebSocket Clientを作成
次に、WebSocket Clientを作成します。
WebSocket Clientのプロジェクトは、ローカルフォルダのいずれの場所に作成しても問題ありません。
今回は「/Users/ユーザー」に「SampleWebSite」というディレクトリを作成しました。
このディレクトリに格納するファイルは下記の2つです。
- index.html
- script.js
サンプルコードは以下のように記述しました。
■記述例(index.html)
■記述例(index.html) <!DOCTYPE html> <html> <head> <title>WebSocketServerのサンプル</title> <meta charset="utf-8" /> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script src="script.js"></script> </head> <body> <p id="message"></p> </body> </html>
WebSocketの通信部分はjQueryを使うため、headタグ内にjQueryのCDNを記述しています。
bodyタグ内にはpタグを用意し、JavaScriptで受信したメッセージをWebページに表示するよう「id=”message”」を設定しました。
■記述例(script.js) $(function() { var url = "ws://localhost:8080/SampleServer/WebSocketServer"; var ws = new WebSocket(url); ws.onmessage = function(receive) { $("#message").text(receive.data); }; ws.onopen = function() { ws.send("WebSocketでメッセージを送信します!"); console.log("メッセージを送信しました!"); }; });
変数 url には、プロジェクト名とエンドポイントを明記するよう下記のように設定しています。
「ws://localhost:8080/プロジェクト名/エンドポイント」
WebSocket Serverに「WebSocketでメッセージを送信します!」というメッセージを送信し、受け取ったメッセージは
$("#message").text(receive.data);
で、index.htmlのpタグへ渡します。
Java WebSocketの動作確認
最後に動作を確認しましょう。
WebSocket Serverを起動するために、WebSocketServer.javaを右クリックして「実行」から該当サーバーを起動します。
WebSocket Serverを起動させたら、index.htmlファイルを開きましょう。
開いた時に「WebSocketでメッセージを正常に受信しました!」と表示されていれば、正常に動作しています。
コンソールも確認してみると、メッセージを送信できていることもわかります。
Eclipseも確認してみると、セッションの確立と受信したメッセージが表示されているはずです。
index.htmlファイルを閉じるとセッションは終了します。
アノテーションは、注釈・注記といった意味の言葉です。
Javaのコード上では「@(アットマーク)」から記述を始め、コードでは表現しきれない情報を補足としてつけ加えます。