前田 航汰 authored on 2 Feb 2023
gradle/ wrapper initial commit 1 year ago
src initial commit 1 year ago
.gitignore initial commit 1 year ago
README.md Update README.md 1 year ago
build.gradle initial commit 1 year ago
gradlew initial commit 1 year ago
gradlew.bat initial commit 1 year ago
settings.gradle initial commit 1 year ago
README.md

WebSocketServerSample

概要

ローカルにWebSocketサーバーをたてるサンプルアプリ。 WebSocketで通信を行うファイルを作り、そのファイルをConfigファイルに設定する必要がある。 SpringBootを使っていなければConfigファイル無しでも動いたが、 SpringBootでRestなAPIと併用してWebSocketを使う場合、Configファイルでの設定が必要になると思う。

各ファイルのポイント

Build.gradle

下の2行を追加する(二行目は追加されてる場合が多いかも)

dependencies { 
    //(省略) 
    implementation 'org.springframework.boot:spring-boot-starter-websocket'
    implementation 'org.springframework.boot:spring-boot-starter-jersey' 
}

WebSocketConfig.java

Configファイルの作成方法があまり出てこなかった。下の2つの記事を参考に書いたら出来た。 作ったWebSocketコードのファイルは、このConfigファイルで@Beanしないと動かない。

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer { 

    @Override 
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 
        //registry.addHandler(unitWebSocketHandler, "/unit").setAllowedOrigins("*"); 
    }

    /*  
    ここめっちゃ大事!!
    ローカルで実行するときは、下3行のBean定義が必要。(入れないとWebSocketのコードが動かなくなる)
    サーバーで実行するときは、下3行のBean定義が不要。(消さないと全てのコードが動かなくなる)
    これで2週間くらい躓いた...
    */
    @Bean
    public WebSocketDemo webSocketDemo() { 
        return new WebSocketDemo(); 
    }

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter(); 
    } 
}

通信部分のコード

下の例は、現在の時刻を5秒に1回送信するサンプル。 下の記事を参考にした。

// ここがURLのエンドポイントになる。
@ServerEndpoint("/WebSocketDemo") 
public class WebSocketDemo { 
    private static final Queue<Session> sessions = new ConcurrentLinkedQueue<>(); 

    static { 
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(); 
        service.scheduleWithFixedDelay(WebSocketDemo::broadcast, 5, 5, TimeUnit.SECONDS); 
    } 

    @OnMessage
    public String onMessage(String message) { 
        System.out.println("WebSocketで受信したメッセージ/ " + message); 
        return "WebSocketでメッセージを正常に受信しました!"; 
    } 

    @OnError
    public void onError(Throwable th) { 
        System.out.println("WebSocketエラーが発生/ " + th.getMessage()); 
    }

    @OnOpen
    public void onOpen(Session session) {
        System.out.println("WebSocketセッション確立");
        sessions.add(session); 
    }

    @OnClose
    public void onClose(Session session) {
        System.out.println("WebSocketセッション終了"); 
        sessions.remove(session); 
    }

    public static void broadcast() { 
        Date now = new Date(); SimpleDateFormat formatter = new 
        SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
        sessions.forEach(session -> { 
            session.getAsyncRemote().sendText("Broadcast : " + formatter.format(now)); 
        }); 
    }

}

もしパラメータを付けたい場合、 URIパス には @ServerEndpoint("/chat/{user}")のようにパスパラメータを定義できる。 これで、@PathParamを通して以下のようにパラメータを取得可能。

@OnOpen
public void onOpen(Session session, @PathParam("user") String user) { }

参考

WebSocketとJSONを組み合わせる場合、下の記事が参考になった。