手把手教你入门vue+springboot开发(十)--springboot集成WebSocket
这篇文章主要介绍了如何在Spring Boot中集成WebSocket协议,实现后端与前端之间的消息通信。文章详细讲解了在后端实现WebSocket服务端和客户端的配置与实现,包括使用org.springframework.boot-starter-websocket依赖、配置WebSocketConfig和WebServerEndpoint类,以及如何通过ObjectMapper将Java对象转换为JSON格式进行通信。此外,文章还介绍了前端如何通过修改App.vue文件实现WebSocket客户端的连接与消息处理,并通过Postman进行了调试,验证了通信的正确性。文章最后总结了整个实现过程,并提到后续将介绍Token的使用。
文章目录
- 引言
- 第一部分Spring Boot WebSocket集成
- 第一部分第一节WebSocket服务端实现
- 第一部分第二节业务逻辑实现
- 第一部分第三节ObjectMapper的作用
- 第二部分后端代码实现
-
第二部分第一节WebSocket服务端实现
-
第二部分第二节业务逻辑实现
-
第二部分第三节ObjectMapper的作用
-
三、前端代码实现
-
四、postman调试
-
总结
-
前言
在B/S开发的某些业务场景中,后端需要向用户推送特定事件信息,例如,当某个用户登录或退出时,后端应通知所有当前登录的用户。显然,HTTP协议无法满足这一需求,于是,我们可以采用WebSocket协议,并探讨如何在Spring Boot中集成该协议以实现上述功能。
一、springboot集成WebSocket
pom.xml增加websocket依赖,如下:
<!--websocket依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
二、后端代码实现
1.WebSocket服务端实现
开发一个WebSocket包,并新增WebSocketConfig和WebServerEndpoint两个类模块,以构建WebSocket服务端接口。
package com.example.demo.websocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
// 需要注入Bean的话必须声明为配置类
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
WebServerEndpoint.java代码如下:
package com.example.demo.websocket;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
// 监听哪些客户端来连接了WebSocket服务端
// 监听websocket地址 /myWs
@ServerEndpoint("/myWs")
@Component
@Slf4j
public class WebServerEndpoint {
// 因为可能有多个客户端所以这里需要保证线程安全
static Map<String, Session> sessionMap = new ConcurrentHashMap<>();
// 建立连接时执行的操作
@OnOpen
public void onOpen(Session session){ // 每个websocket连接对于服务端来说都是一个Session
sessionMap.put(session.getId(),session);
log.info("websocket is open");
}
/** * 收到客户端消息时执行的操作
* @param text 接受到客户端的消息
* @return 返回给客户端的消息
*/
@OnMessage
public String onMessage(String text){
log.info("收到一条新消息: " + text);
return "收到 !";
}
// 连接关闭时执行的操作
@OnClose
public void onClose(Session session){
sessionMap.remove(session.getId());
log.info("websocket is close");
}
public void sendmsg(String msg) {
if(sessionMap.isEmpty()){return;}
try {
for (String key : sessionMap.keySet()) { // 给所有客户端发送消息
sessionMap.get(key).getBasicRemote().sendText(msg);
log.info("websocket sendmsg:" + msg);
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
该 WebSocket 协议提供了多个事件回调函数,支持服务端与客户端双向通信。onopen 事件:当服务端响应 WebSocket 连接请求时,该事件触发并建立连接,其对应的回调函数名为 onopen。onmessage 事件:在接收到消息时触发,其对应的回调函数名为 onmessage。onerror 事件:在响应意外故障时触发,其对应的回调函数名为 onerror。onclose 事件:当 WebSocket 连接关闭时触发,其对应的回调函数名为 onclose。一旦发生连接关闭,客户端与服务器将无法进行消息接收或发送。通过 sessionMap.get(key).getBasicRemote().sendText(msg) 方法,服务端能够向指定的客户端发送消息。
2.业务逻辑实现
在用户登录成功后向其他已登录用户推送登录事件,在WebSocket发送事件的业务逻辑上,应避免将逻辑放置于UserController中,而应将其置于UserService中。因为Controller主要负责与前端交互,而Service则负责具体业务处理。
void sendLogin(String username) throws JsonProcessingException;
2)UserServiceImpl.java增加sendLogin实现
@Autowired
private WebServerEndpoint webServerEndpoint;
@Override
public void sendLogin(String username) throws JsonProcessingException{
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("login_user", username);
String info = mapper.writeValueAsString(jsonMap);
webServerEndpoint.sendmsg(info);
}
3)UserController.java登录函数中增加:
try {
userService.sendLogin(username);
} catch (IOException e) {
e.printStackTrace();
}
3.ObjectMapper的作用
在我们的业务代码实现过程中,经常需要进行Java对象与JSON字符串之间的转换。ObjectMapper是Jackson库中的一个重要类,该类提供了将JSON数据与Java对象之间进行相互转换的功能。具体来说,该类能够完成以下两种转换操作:首先,该类能够将Java对象转换为JSON格式的字符串,这种操作便于数据的传输和存储;其次,该类还能够将JSON字符串转换为Java对象,这种操作则方便在代码中进行数据处理和操作。
三、前端代码实现
修改前端demo的App.vue文件,script中实现WebSocket客户端代码。
<script setup>
// 客户端和服务器连接的地址(我们服务端监听的地址)
let ws = new WebSocket("ws://localhost:8080/myWs")
ws.onopen=function (){ // 连接打开的时候向服务器发送一条消息
ws.send("hello")
}
ws.onmessage=function (message) {
console.log(message.data) // 服务器返回的消息
}
</script>
四、postman调试
1)启动Spring Boot后端服务。
2)启动前端演示程序,并在浏览器中访问 localhost:5173。
后端Spring Boot服务通过WebSocket客户端接收到“hello”消息,并在日志中进行了记录。

前端demo收到“收到”消息,日志如下图:

3)postman发送login消息。

4)
4)
4)

前端demo收到admin登录事件,日志如下图:

总结
本文主要探讨Spring Boot集成WebSocket实现后端向端上报消息事件的技术方法。其中,WebSocket协议可作为HTTP协议的补充,以实现一些HTTP协议无法单独完成的业务功能。值得注意的是,WebSocket还可以作为一个独立的TCP协议通道进行通信,目前我们暂不深入研究,后续有机会会与大家分享相关应用。在下篇文章中,我们将深入解析Token的使用方法。
