LoginSignup
3
6

More than 5 years have passed since last update.

Java-WebSocket v1.2.0

Posted at

Java で WebSocket を扱おうとすると、javax.websocketの使い方に関する記事がかなりヒットするのですが(Google 日本語検索だとね)、正直言って、もっとライトに試してみたいというのが本音。

"java websocket" を Google 英語検索すると、以下のライブラリがトップに出ました。

Java-WebSocket

こいつがかなり手軽に Java Websocket を書けそうなものだったので試してみました。

Java-WebSocket とは

java.nio が提供する non-blocking イベントドリブンモデルを利用した、100% Java で書かれている WebSocket Server だそうです。

java.nio って non-blocking な IO が可能なんですね。
恥ずかしながら初めて知りました。
参考

サポートされている WebSocket プロトコルのバージョンはこちらだそうです。

Build

Ant か maven でビルドできます。
今回は maven を使います。

早速動かしてみましょう。
まずはビルド。

% git clone git@github.com:TooTallNate/Java-WebSocket.git
% cd Java-WebSocket
% mvn package  
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Java WebSocket 1.3.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 53.567 s
[INFO] Finished at: 2016-05-28T17:46:00+09:00
[INFO] Final Memory: 25M/206M
[INFO] ------------------------------------------------------------------------

オーケー。
続いてデモっぽいのを動かしてみます。

% java -cp build/examples:dist/java_websocket.jar ChatServer
エラー: メイン・クラスChatServerが見つからなかったかロードできませんでした

むむむ・・・。
maven からビルドした場合は、サンプルないのかな??

残念です。

しかしながら、あまり難しくはなさそうなので、自分で WebSocket サーバを実装してみます。

WebSocketServer の書き方

org.java_websocket.server.WebSocketServer 抽象クラスを継承して、コードを付け足すことでできるそうです。

WebSocketClient の書き方

org.java_websocket.server.WebSocketServer 抽象クラスを継承して、コードを付け足すことでできるそうです。

WSS Support

面倒臭いので飛ばします。
またの機会に・・・。

実際に書いてみる

WebSocketServer

まずはこいつの jar を取得します。
Maven にあったので、それを使います。

% curl -OL http://central.maven.org/maven2/org/java-websocket/Java-WebSocket/1.3.0/Java-WebSocket-1.3.0.jar

続いて、コードを書きます。
こちらを参考にします。
コピーペーストしてちょっとだけ編集したのがこちら。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Collection;

import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

public class ChatServer extends WebSocketServer {

  public ChatServer( int port ) throws UnknownHostException {
    super ( new InetSocketAddress( port ) );
  }

  @Override
  public void onOpen( WebSocket connection, ClientHandshake handshake ) {
    System.out.println( connection.getRemoteSocketAddress().getAddress().getHostAddress() + " entered the room!" );
  }

  @Override
  public void onClose( WebSocket connection, int code, String reason, boolean remote ) {
    System.out.println( connection + " has left the room!" );
  }

  @Override
  public void onMessage( WebSocket connection, String message ) {
    System.out.println( connection + ": " + message );
    Collection<WebSocket> websockets = connections();
    synchronized ( websockets ) {
      for ( WebSocket websocket: websockets ) {
        websocket.send(message);
      }
    }
  }

  @Override
  public void onError( WebSocket connection, Exception e ) {
    e.printStackTrace();
  }

  public static void main( String[] args ) throws InterruptedException, IOException {
    ChatServer server = new ChatServer( 8887 );
    server.start();
    System.out.println( "ChatServer started on port: " + server.getPort() );
  }
}

コンパイル

% javac -cp Java-WebSocket-1.3.0.jar ChatServer.java

WebSocketClient

こいつは、ブラウザの WebSocket を用いることにしました。

<!DOCTYPE html>
<html>
<head>
  <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  <title>Sample client of Java_WebSocket_Sample</title>
</head>
<script>
var websocket = new WebSocket("ws://localhost:8887");
websocket.onopen = function () {
  console.log("Connection is opened!");
};
websocket.onclose = function () {
  console.log("Connection is closed!");
};
websocket.onmessage = function (e) {
  console.log(e);
  var data = JSON.parse(e.data);
  var slMessage = d3.select("#messages").append("div")
    .attr("class", "message")
  ;
  slMessage.append("span").attr("class", "name").text(data.name + ":");
  slMessage.append("span").attr("class", "say").text(data.say);
};
websocket.onerror = function () {
  console.log("Error is occured!");
};

window.addEventListener("load", function () {
  d3.select("#name")[0][0].value = "名無しのごんべえ";
  d3.select("#post").on("click", function () {
    var say = d3.select("#say")[0][0].value;
    var name = d3.select("#name")[0][0].value;
    if (say.length === 0) { return ; }
    d3.select("#say")[0][0].value = "";
    websocket.send(JSON.stringify({say: say, name: name}));
  });
});
</script>
<body>
  <input type="text" id="name"></input>
  <input type="text" id="say" placeholder="Say something!!"></input>
  <button type="text" id="post">say</button>
  <div id="messages">
  </div>
</body>
</html>

テスト

サーバ起動します

% java -cp .:Java-WebSocket-1.3.0.jar ChatServer
ChatServer started on port: 8887

タブを2つ開きます

スクリーンショット 2016-05-28 20.08.58.png

メッセージを入れてみましょう

スクリーンショット 2016-05-28 20.11.33.png

どうやらうまく動いたようです
ちなみにサーバ側の標準出力はこちら。

% java -cp .:Java-WebSocket-1.3.0.jar ChatServer
ChatServer started on port: 8887
0:0:0:0:0:0:0:1 entered the room!
0:0:0:0:0:0:0:1 entered the room!
org.java_websocket.WebSocketImpl@6207ffd1: {"say":"こっぱみじんにしてやる。","name":"⭕️りーざ"}
org.java_websocket.WebSocketImpl@6207ffd1: {"say":"あの地球人のようになぁ・・・","name":"⭕️りーざ"}
org.java_websocket.WebSocketImpl@6207ffd1: {"say":"ふっふっふっふっふっふ・・・","name":"⭕️りーざ"}
org.java_websocket.WebSocketImpl@6cb09aae: {"say":"あの地球人のようにだと?!","name":"⭕️くう"}
org.java_websocket.WebSocketImpl@6cb09aae: {"say":"クリリンのことか!","name":"⭕️くう"}
org.java_websocket.WebSocketImpl@6cb09aae: {"say":"クリリンのことかーーー!!","name":"⭕️くう"}

java にしてはすばらしく手軽ですが、本番運用に耐えうるライブラリかどうか?というとそれはわかりませんね・・・。

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6