原文地址:https://dwz.cn/Z1O56dnu
前言
本文中搭建了一個簡易的多人聊天室,使用了WebSocket的基礎特性。
https://www.callicoder.com/spring-boot-websocket-chat-example/
本文內容摘要:
初步理解WebSocket的前後端交互邏輯手把手使用 SpringBoot + WebSocket 搭建一個多人聊天室Demo代碼源碼及其解釋前端展示頁面此外,在下一篇文章中,我們將做到:
對該WebSocket聊天室進行分佈式改造,同時部署多臺機器來作為集群,支撐高併發。保存用戶session,並且在集群上實現session同步,比如實時展示當前在線的用戶!正文
WebSocket多人在線聊天室
本文工程源代碼:
https://github.com/qqxx6661/springboot-websocket-demo
新建工程
我們新建一個SpringBoot2的項目工程,在默認依賴中,添加websocket依賴:
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-websocket/<artifactid>
/<dependency>
WebSocket 配置
我們先來設置websocket的配置,新建config文件夾,在裡面新建類WebSocketConfig
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.*;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
代碼解釋:
@EnableWebSocketMessageBroker用於啟用我們的WebSocket服務器。
我們實現了WebSocketMessageBrokerConfigurer接口,並實現了其中的方法。
在第一種方法中,我們註冊一個websocket端點,客戶端將使用它連接到我們的websocket服務器。
withSockJS()是用來為不支持websocket的瀏覽器啟用後備選項,使用了SockJS。
方法名中的STOMP是來自Spring框架STOMP實現。STOMP代表簡單文本導向的消息傳遞協議。它是一種消息傳遞協議,用於定義數據交換的格式和規則。為啥我們需要這個東西?因為WebSocket只是一種通信協議。它沒有定義諸如以下內容:如何僅向訂閱特定主題的用戶發送消息,或者如何向特定用戶發送消息。我們需要STOMP來實現這些功能。
在configureMessageBroker方法中,我們配置一個消息代理,用於將消息從一個客戶端路由到另一個客戶端。
第一行定義了以“/app”開頭的消息應該路由到消息處理方法(之後會定義這個方法)。
第二行定義了以“/topic”開頭的消息應該路由到消息代理。消息代理向訂閱特定主題的所有連接客戶端廣播消息。
在上面的示例中,我們使用的是內存中的消息代理。
之後也可以使用RabbitMQ或ActiveMQ等其他消息代理。
創建 ChatMessage 實體
ChatMessage用來在客戶端和服務端中交互
我們新建model文件夾,創建實體類ChatMessage。
實體中,有三個字段:
type:消息類型content:消息內容sender:發送者類型有三種:
CHAT: 消息JOIN:加入LEAVE:離開創建Controller來接收和發送消息
創建controller文件夾,在controller文件夾添加類ChatController
代碼解釋:
我們在websocket配置中,從目的地以/app開頭的客戶端發送的所有消息都將路由到這些使用@MessageMapping註釋的消息處理方法。
例如,具有目標/app/chat.sendMessage的消息將路由到sendMessage()方法,並且具有目標/app/chat.addUser的消息將路由到addUser()方法
添加WebSocket事件監聽
完成了上述代碼後,我們還需要對socket的連接和斷連事件進行監聽,這樣我們才能廣播用戶進來和出去等操作。
創建listener文件夾,新建WebSocketEventListener類
代碼解釋:
我們已經在ChatController中定義的addUser()方法中廣播了用戶加入事件。因此,我們不需要在SessionConnected事件中執行任何操作。
在SessionDisconnect事件中,編寫代碼用來從websocket會話中提取用戶名,並向所有連接的客戶端廣播用戶離開事件。
創建前端聊天室頁面
我們在src/main/resources文件下創建前端文件,結構類似這樣:
static
└── css
└── main.css
└── js
└── main.js
└── index.html
1. HTML文件 index.html
HTML文件包含用於顯示聊天消息的用戶界面。它包括sockjs和stomp 兩個js庫。
SockJS是一個WebSocket客戶端,它嘗試使用本機WebSockets,併為不支持WebSocket的舊瀏覽器提供支持。STOMP JS是javascript的stomp客戶端。
筆者在文件裡使用了國內的CDN源
2. JavaScript main.js
添加連接到websocket端點以及發送和接收消息所需的javascript。
代碼解釋:
connect()函數使用SockJS和stomp客戶端連接到我們在Spring Boot中配置的/ws端點。
成功連接後,客戶端訂閱/topic/public,並通過向/app/chat.addUser目的地發送消息將該用戶的名稱告知服務器。
stompClient.subscribe()函數採用一種回調方法,只要消息到達訂閱主題,就會調用該方法。
其它的代碼用於在屏幕上顯示和格式化消息。
3. CSS main.css
整個項目結構如下:
啟動
啟動SpringBoot項目
效果入下:
補充:使用RabbitMQ代替內存作為消息代理
添加依賴:
然後將WebSocketConfig類中configureMessageBroker方法改為使用RabbitMq,完成!
如此一來,便可以通過RabbitMq進行消息的訂閱。