ページ

2015年10月17日土曜日

JavaEE7でWebSocket

ここのところお仕事が忙しくてなかなかプログラムで遊ぶことがなかったのですが、今日は雨で子供たちの予定がなくなったのでお勉強がてらいじってみました。

お題は「JavaEE7でWebSocket」です。
バイナリデータをWebSocketサーバで受けたいなというのがそもそもの思いです。

サーバ側はこんなです。

--------------------------------------------------
package sample; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.websocket.OnOpen; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/endpoint") public class NewWSEndpoint { private static FileChannel channel = null; @OnOpen public void onOpen(Session session){ try { channel = new FileOutputStream(new File("output.dat")).getChannel(); System.out.println("OnOpen"); } catch (FileNotFoundException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnClose public void onClose(Session session){ try { channel.close(); System.out.println("OnClose"); } catch (IOException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnMessage public String onMessage(Session session, String message) { System.out.println("OnMessage String = " + message); return null; } @OnMessage public void onMessage(Session session, ByteBuffer byteBuffer) { try { channel.write(byteBuffer); System.out.println("OnMessage binary = " + byteBuffer.toString()); } catch (IOException ex) { Logger.getLogger(NewWSEndpoint.class.getName()).log(Level.SEVERE, null, ex); } } @OnError public void onError(Throwable t) { System.out.println("OnError"); } } --------------------------------------------------

接続を受けたときにファイルを生成し、バイナリデータを受けたときに書きだし、切断を検出したときにファイルをクローズするというシンプルなものです。ちなみにテキストデータを受けたときはprintlnしてるだけです。

これを試すクライアント側です。とりあえず簡単に試したいのでJavaScriptにしてみました。

--------------------------------------------------
<html> <head> <title>JavaEE7 WebSocket Test</title> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script type="text/javascript"> var socket; $(document).ready(function(){ socket = new WebSocket("ws://localhost:8080/TestWebSocket/endpoint"); $('#send').click(function(){ // テキストボックスから文字列取得 var text = $('#message').val(); // テキスト送信 socket.send(text); // 文字列のアスキーコードを代入 var length = text.length; var binary = new Uint8Array(length); for (var i = 0; i < length; i++) { binary[i] = text[i]; } // バイナリ送信 socket.send(binary.buffer); }); }); </script> </head> <body> <input id="message" type="text" /> <button id="send">Send</button> <div id="messages"> </div> </body> </html> --------------------------------------------------

それにしても非常に少ないソースコードでサーバが実現できますね。すばらしい。