Spring – Stompを利用したwebsocketチャットサーバー(1)

WebSocketとは

WebSocketとは既存の片方向HTTPプロトコルと互換されていて両方向通信を提供するために開発されたプロトコルです。

一般のsocket通信とは違ってHTTP 80 Portを利用するので防火壁に制約がなく、通常Websocketと呼ばれます。

接続まではHTTPプロトコルを利用してその後の通信はWebsocketプロトコルで通信を行います。

Stompとは

STOMPは「Simple (or Streaming) Text Orientated Messaging Protocol」の略で、軽量なメッセージングプロトコルです。 TCPやWebSocket上で利用できます。

基本的にpub/sub構造になっていてメッセージを発送してメッセージを受信処理を行う部分が決められているため、開発時に明確に認知し、開発できる利点があります。

また、Stompを利用すると通信メッセージのヘッダーに値をセットできるのでヘッダー値を利用して通信時に認証処理を行うこともできます。

pub/subとは

メッセージを供給する主体と消費する主体を分離して提供するメッセージング方法です。

  • チャットルームを作成:pub/sub構築のためのTopicが1つ生成される。
  • チャットに参加する:Topicを登録する。
  • チャットルームでメッセージをやり取りする:該当Topicでメッセージを送ったり(pub)メッセージを受ける(sub)

Stompを利用してチャットを構築

プロジェック構成

build.gradle

  • webjar:チャットのウェブ画面を構築するために必要なjsをロードするために使います。
  • implementation ‘org.webjars.bower:vue:2.5.16’:フロント(画面)開発のために使います。
  • implementation ‘org.springframework.boot:spring-boot-starter-freemarker’:フロント(画面)開発のために使います。
  • implementation ‘org.webjars:stomp-websocket:2.3.3-1’:stompで通信をするため、必要なjsです。
  • implementation ‘org.webjars:sockjs-client:1.1.2’:Websocketを支援していない低いバージョンのブラウザでもWebsocketを使用できるようにしてくれるライブラリーです。

Application設定

  • @SpringBootApplication:Springbootの自動設定、Spring Bean読み取り、生成の全てを自動に設定されます。
    • @SpringBootApplicationがある位置から設定を読み込んでいくのでこのクラスはいつもプロジェックの最上位に置かなければなりません。
  • SpringApplication.run:内装WAS(Web Application Server)を実行します。

※内装WASは別途で外部にWASを置かなくてアプリケーションを実行するとき内部でWASを実行することを言います。そうなると常にサーバーにTomcatをインストールする必要がなくなります。

application.yml作成

IntelliJでstaticファイルを開発するときサーバーを再起動しなくても修正した内容が反映されるように上記のように設定します。

WebSockConfig作成

  • Stompを使用するために@EnableWebSocketMessageBrokerを宣言します。
  • WebSocketMessageBrokerConfigurerを継承してconfigureMessageBrokerを作成します。
  • pub/subメッセージングを実現するため、メッセージを発行するリクエストのprefixは/pubで始めるようにセットします。
  • メッセージを登録するリクエストのprefixは/subで始めるようにセットします。
  • stomp websocketの接続のendpointは/ws-stompで設定します。
    • なので開発サーバーの接続アドレスは「ws://localhost:8080/ws-stomp」になります。

ChatMessage作成

  • チャットメッセージをやり取りするためのDTOです。
  • 上記によってチャットルーム参加、メッセージを送信の2つがあるので、enumを宣言します。
  • メンバーフィールドとしては以下となります。
    • id:チャットルームの区別
    • sender:メッセージを送信したユーザー
    • message:メッセージ

チャットルーム作成

  • ChatRoom:チャットルームを作成するためのDTOです。
  • roomId:チャットルームid
  • name:チャットルーム名

※UUIDについてはこちらを参考してください。

ChatController作成

  • @MessageMapping:Webscoket経由のメッセージ発行の処理を行います。
  • クライアントからはprefixを付けて/pub/chat/messageに発行リクエストをするとControllerが該当メッセージを受け取って処理します。
  • /sub/chat/room/{roomId}
    • クライアントでは該当アドレス(/sub/chat/room/{roomId})を登録していてメッセージが渡されたら画面に表示します。
    • /sub/chat/room/{roomId}はチャットルームを区分する値なので、pub/subでTopicの役割行います。

チャットロームのRepository作成

  • ChatRoomRepository:チャットルームを生成して情報を照会するRepositoryクラスです。
  • private Map<String, ChatRoom> chatRoomMap:チャットルーム情報を管理するため、Mapを宣言します。

ChatRoomController作成

  • ChatRoomController:Websocket通信いがにチャット画面のViewを構成するため、必要なControllerです。
  • 各メソッド:各メソッドの役割はコードのコメントに書いておきました。

次回は画面の開発をしていきたいと思います。

全てのソースコードは以下のあります。

Github link

参考

Daddyprogrammer

コメントを残す