JavaのWebアプリケーション開発フレームワークによる、Webサイト開発の顛末記です。

EclipseのMavenを使った、Spring-MVC、Thymeleaf、MyBatis 等のプログラミングテクニックを、
備忘録的に記録しています。実際に動くソースコードを多用して説明していますので、
これからEclipseや、Spring-MVCを始めたいと思っている人にとって、少しでも参考になれば幸いです。
Spring-MVCの散歩道 > 応用の森(総合テクニック編) > WebSocketを使った、リアルタイムCPU使用率推移グラフ

package jp.dip.arimodoki.websocket;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import jp.dip.arimodoki.common.CConst;

/**
 * CPU使用率を返すWebSockHandlerクラスです
 */
public class CPUHandler extends TextWebSocketHandler implements CConst {

    /** セッション一覧 */
    private Map<String, WebSocketSession> sessionMap_ = new ConcurrentHashMap<>();

    /**
     * Clientごとに実行するRunnableスレッドオブジェクトのマップ
     * session.getId()をHashMapのキーとして持つ
     */
    private Map<String, CPUHandlerRun> handleMap = new HashMap<>();

    /**
     * WebSocket接続時に実行されるメソッド
     */
    @Override  //afterConnectionEstablishedをオーバーライドします
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        if(this.sessionMap_.size()>=100) {
            logger.log_error(this,"too many Connection");
            throw new Exception("too many Connection");
        }
        this.sessionMap_.put(session.getId(), session);
    }

    /**
     * WebSocket切断時に実行されるメソッド
     */
    @Override  //afterConnectionClosedをオーバーライドします
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        this.sessionMap_.remove(session.getId());
        //スレッドマップから自分のSessionIDのキーを持つスレッドを探す
        CPUHandlerRun thmap = this.handleMap.get(session.getId());
        if(thmap != null) {
            thmap.stop();   //Runnableスレッドを停止
            //キーが居たらスレッドマップから削除
            this.handleMap.remove(session.getId());
        }
    }

    /**
     * ClientからのWebSocketメッセージ受信時に実行されるメソッド
     */
    @Override  //handleTextMessageをオーバーライドします
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        CPUHandlerRun run = null;

        //スレッドマップから自分のSessionIDのキーを持つスレッドを探す
        CPUHandlerRun thmap = this.handleMap.get(session.getId());
        if(thmap == null) {
            //キーがいなかったら新しくインスタンスを起こして、スレッドマップに登録
            run = new CPUHandlerRun(session,this.sessionMap_);
            this.handleMap.put(session.getId(), run);
        } else {
            //キーが居たらそれが自分のスレッド
            run = thmap;
        }
        //Clientからなんか来た
        if(message.getPayload().equals("stop")) {
            //"stop"が来たのでRunnableスレッドを停止する
            run.stop();
            //スレッドマップから削除する
            this.handleMap.remove(session.getId());
        } else {
            //"stop"じゃなければ、Runnableスレッドを開始する
            run.start();
        }
    }

}