Java 8 Launchイベントに参加してきました。

久しぶりの記事です。
と言っても、まだ二回目ですが。。。

3/21(金)に開催された、「祝☆Java 8 Launch」に参加してきました。

ここで張り切って、誰がどのような内容の発表したとか
記述しようと思ったのですが、既に色んな人が書いているので
やめることにします。

とりあえず思ったことは、

  • みんなすごい
  • 自分は井の中の蛙だった
  • 登壇者に大学2年生がいたのが最大の驚き

でした。

色々刺激になってすごく有意義な時間を過ごすことができたので、
これからもどんどん参加して行きたいと思います。
もちろん参加するだけではなく、ゆくゆくは発表も行いたいですね。

次回からは、何かしら技術ネタを書いていこうと思ってます。
あまり期間が空かないうちに。。。

Tomcat7+jquery-websocketを使ったチャットサンプル

Tomcat7+jquery-websocketを使ったチャットサンプル。

まずは、Tomcatjqueryの各モジュールをダウンロード
Apache Tomcat® - Welcome!
jQuery
GitHub - Krinkle/jquery-json: [Discontinued] Use native JSON.stringify and JSON.parse instead, or json2.js from https://github.com/douglascrockford/JSON-js
Google Code Archive - Long-term storage for Google Code Project Hosting.

Tomcatを使う場合、サーバ側はorg.apache.catalina.websocket.WebSocketServletを継承してServletを作成する。

サンプルプログラムと画面は以下の通り。

  • index.html(クライアント側)
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<script type="text/javascript" src="js/lib/jquery-1.7.2.min.js"></script>
	<script type="text/javascript" src="js/lib/jquery.json-2.3.min.js"></script>
	<script type="text/javascript" src="js/lib/jquery.websocket-0.0.1.js"></script>
	<title>WebSocket Sample</title>
</head>
<script type="text/javascript">
$(document).ready(function(){
        // WebSocket通信用モジュール生成
	var ws = $.websocket("ws://localhost:8080/sample_websocket/sample/", {
                // メッセージイベント
		events: {
                        // サーバ側からメッセージ通信を受信した場合の動作
			message: function(e) {$("#content").append(e.data + "<br>")}
		}
	});
        // フィールドの更新イベントの設定
	$("#message").change(function(){
                // メッセージイベントで送信
		ws.send("message", this.value);
		this.value = "";
	});	
});

</script>
<body>
  <section id="content">
  </section>
  <input type="text" value="" id="message">
</body>
</html>
  • SampleWebsocketServlet.java(サーバ側)
package sample.websocket.servlet;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.annotation.WebServlet;

import net.arnx.jsonic.JSON;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;
import org.apache.catalina.websocket.WsOutbound;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

@WebServlet(urlPatterns = { "/sample/" })
public class SampleWebsocketServlet extends WebSocketServlet {

  private Log log = LogFactory.getLog(getClass());

  /**
   * SerialVersionUID.
   */
  private static final long serialVersionUID = -5071060990676493696L;

  // ユーザ名用
  private static final String GUEST_PREFIX = "Guest_%02d";
  // ユーザID生成用
  private final AtomicInteger ids = new AtomicInteger(0);
  // ユーザコネクション保持用
  private final Set<SampleMessageInbound> connections = new CopyOnWriteArraySet<>();

  /**
   * コネクション生成時のメソッド
   */
  @Override
  protected StreamInbound createWebSocketInbound(String arg0) {
    log.info(arg0);
    return new SampleMessageInbound(ids.incrementAndGet());
  }

  /**
   * 通信用クラス
   */
  private class SampleMessageInbound extends MessageInbound {

    // ユーザ名
    private String name;

    public SampleMessageInbound(int id) {
      name = String.format(GUEST_PREFIX, id);
    }

    @Override
    protected void onBinaryMessage(ByteBuffer arg0) throws IOException {
    }

    /**
     * テキストメッセージ受信時のメソッド
     */
    @Override
    protected void onTextMessage(CharBuffer message) throws IOException {
      // Never trust the client
      // jsonをオブジェクトにマッピング
      Message m = JSON.decode(message.toString(), Message.class);
      String filteredMessage = String.format("%s: %s", name, m.data);

      log.info(filteredMessage);
      broadcast(filteredMessage);
    }

    /**
     * コネクション開始のメソッド
     */
    protected void onOpen(WsOutbound outbound) {
      connections.add(this);
      String message = String.format("%s %s", name, "has joined.");
      log.info(message);
      broadcast(message);
    }

    /**
     * コネクション終了のメソッド
     */
    @Override
    protected void onClose(int status) {
      connections.remove(this);
      String message = String.format("%s %s", name, "has disconnected.");
      log.info(message);
      broadcast(message);
    }

    private void broadcast(String message) {
      log.info(message);
      for (SampleMessageInbound connection : connections) {
        try {
          CharBuffer buffer = CharBuffer.wrap(JSON
              .encode(new Message(message)));
          log.info(JSON.encode(new Message(message)));
          connection.getWsOutbound().writeTextMessage(buffer);
        } catch (IOException e) {
          log.error(e, e);
        }
      }
    }
  }

  private class Message {
    public Message() {
    }

    public Message(String message) {
      this.type = "message";
      this.data = message;
    }

    public String data;
    public String type;
  }
}
  • ユーザ1

  • ユーザ2