随着互联网的发展,多人在线聊天室成为了一个热门的应用场景。WebSocket是一种在单个TCP连接上进行全双工通信的方式,它可以实现实时的双向通信,因此在开发多人在线聊天室时常用到。在本文中,我们将介绍如何使用Spring Boot搭建一个基于WebSocket的多人聊天室。
一、环境搭建
在开始之前,需要安装以下环境:
- JDK 1.8或以上
- Maven
- IntelliJ IDEA(或其他的IDE)
二、创建项目
选择一个空的Spring Boot项目,在pom.xml文件中添加以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
三、编写Java程序
- 创建WebSocketConfig类
在项目的src/main/java目录下创建一个名为WebSocketConfig的Java类,并添加@EnableWebSocket注解,表示启用WebSocket。代码如下:
@Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(chatRoomHandler(),"/chatRoom").withSockJS(); } @Bean public ChatRoomHandler chatRoomHandler() { return new ChatRoomHandler(); } }
registerWebSocketHandlers方法用于注册WebSocket处理程序,这里我们使用ChatRoomHandler作为处理程序,并将它映射到/chatRoom路径上。withSockJS()方法表示启用SockJS支持。
- 创建ChatRoomMessage类
在项目的src/main/java目录下创建一个名为ChatRoomMessage的Java类,用于表示聊天室中的消息。代码如下:
public class ChatRoomMessage { private String content; private String sender; private MessageType type; // 省略getter和setter方法 }
ChatRoomMessage中有三个字段,分别表示消息的内容、发送者和消息类型。MessageType是自定义的枚举类型,表示消息类型。
- 创建ChatRoomHandler类
在项目的src/main/java目录下创建一个名为ChatRoomHandler的Java类,用于处理WebSocket连接和消息的发送和接收。代码如下:
@Component public class ChatRoomHandler extends TextWebSocketHandler { // 保存WebSocketSession列表 private static List<WebSocketSession> webSocketSessions = new CopyOnWriteArrayList<>(); // 处理WebSocket连接建立事件 @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { webSocketSessions.add(session); } // 处理WebSocket连接关闭事件 @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { webSocketSessions.remove(session); } // 处理WebSocket消息接收事件 @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { ChatRoomMessage chatRoomMessage = new ObjectMapper().readValue(message.getPayload(), ChatRoomMessage.class); chatRoomMessage.setSender(session.getId()); broadcast(chatRoomMessage); } // 广播消息给所有WebSocketSession private void broadcast(ChatRoomMessage chatRoomMessage) throws IOException { for (WebSocketSession webSocketSession : webSocketSessions) { webSocketSession.sendMessage(new TextMessage(new ObjectMapper().writeValueAsString(chatRoomMessage))); } } }
ChatRoomHandler继承自TextWebSocketHandler,处理文本格式的WebSocket消息。在类中定义了一个静态的webSocketSessions列表,用于保存所有的WebSocketSession。在WebSocket连接建立时,将新的WebSocketSession加入webSocketSessions列表中,在WebSocket连接关闭时,将WebSocketSession从webSocketSessions列表中移除。在WebSocket消息接收时,将消息转换为ChatRoomMessage对象,并设置发送者为WebSocketSession的ID,并调用broadcast方法将消息广播给所有的WebSocketSession。
- 创建ChatRoomController类
在项目的src/main/java目录下创建一个名为ChatRoomController的Java类,用于处理聊天室页面的渲染和消息的发送。代码如下:
@Controller public class ChatRoomController { @GetMapping("/chatRoom") public String chatRoom() { return "chatRoom"; } @MessageMapping("/sendMessage") @SendTo("/topic/chatRoom") public ChatRoomMessage sendMessage(ChatRoomMessage chatRoomMessage) { return chatRoomMessage; } }
ChatRoomController定义了一个映射到/chatRoom路径上的GET请求,返回聊天室的页面。同时,它还定义了一个映射到/sendMessage路径上的WebSocket消息,使用@SendTo注解将消息发送到/topic/chatRoom路径上。
- 创建Thymeleaf模板
在项目的src/main/resources/templates目录下创建一个名为chatRoom.html的Thymeleaf模板,用于渲染聊天室页面。
<!DOCTYPE html> <html> <head> <title>Spring Boot WebSocket Chat Room</title> <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> <h1>Spring Boot WebSocket Chat Room</h1> <div> <label>Username:</label> <input type="text" v-model="username"/> <button v-on:click="login()">Login</button> </div> <div v-if="loggedIn"> <hr/> <div v-for="message in messages"> <span v-html="message.sender + ': '"></span> <span v-html="message.content"></span> </div> <hr/> <div> <input type="text" v-model="message"/> <button v-on:click="sendMessage()">Send</button> </div> </div> </div> <script> var app = new Vue({ el: '#app', data: { username: '', messages: [], message: '', loggedIn: false, stompClient: null }, methods: { login: function () { var _this = this; var socket = new SockJS('/chatRoom'); this.stompClient = Stomp.over(socket); this.stompClient.connect({}, function (frame) { console.log('Connected:', frame); _this.stompClient.subscribe('/topic/chatRoom', function (payload) { var message = JSON.parse(payload.body); _this.messages.push(message); }); }); this.loggedIn = true; }, sendMessage: function () { var chatRoomMessage = { content: this.message, sender: this.username, type: 'CHAT' }; this.stompClient.send('/app/sendMessage', {}, JSON.stringify(chatRoomMessage)); this.message = ''; } } }); </script> </body> </html>
Thymeleaf模板中包含了一个Vue组件,用于渲染聊天室页面。同时,它还包含了Stomp.js和SockJS的引用,用于建立WebSocket连接和发送和接收消息。
四、运行程序
在IDE中运行程序,访问http://localhost:8080/chatRoom,进入聊天室页面。输入用户名并点击“Login”按钮,即可进入聊天室。在输入框中输入消息并点击“Send”按钮,即可发送消息。
五、总结
本文介绍了如何使用Spring Boot搭建一个基于WebSocket的多人聊天室。通过WebSocket的双向通信特性,可以实现实时交流,为多人在线聊天室应用提供了很大的便利。