投稿

4月, 2014の投稿を表示しています

java.lang.IllegalStateExceptionの対処法

JavaEE7のRemoteEndpoint.Async.sendText()を連続して呼び出すと、java.lang.IllegalStateExceptionがスローされることがあります。 これは、sendText()の処理が終わる前に、再度sendText()が呼び出されたためです。 sendText()の処理は非同期で行われるために、メソッドが戻ってきたとしてもメッセージ送信が終了している保証はありません。 これを防ぐためには、sendText()の戻り値であるFutre型のオブジェクトのget()を呼び出して、処理が終わるのを待つ必要があります。 public void sendMessageToBrowser(String message) { for (Session s : sessions) { Future future = s.getAsyncRemote().sendText(message); try { future.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

websocketのサンプルコードをJavaEEで書いた

JavaEE7にはwebsocketを実装したパッケージ(javax.websocket)が提供されています。 これを使ったサンプルコードを書いてみました。 ブラウザから入力された数字の数だけ、適当な文字列(数字列)を接続している全ブラウザに表示するコードです。 まずはJava側。Servletクラスとかを継承しなくていいみたいです。 注意が必要なのは、RemoteEndpoint.Async.sendText()はFuture型のオブジェクトを返すということ。つまり、sendText()メソッドの処理は非同期で行われます。 sendText()はその仕様として処理が終わる前に、再び呼び出されるとjava.lang.IllegalStateExceptionを送出します。そのため、for文などを用いて繰り返し、メッセージを送りたい場合はFuture.get()などを用いて、処理が終わるのを待ってから次のメッセージを送るようにします。 import java.util.Collections; import java.util.HashSet; import java.util.Random; import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/endpoint") public class Main { static Set<session> sessions = Collections.synchronizedSet(new HashSet<session>()); @OnMessage public void onMessage(Str...