原文地址: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进行消息的订阅。