适用于ruoyi项目,前端为vue,后端为mybatis
部分资料参考若依官网文档插件集成 | RuoYi
-
业务场景
实现前端与后端的长时间稳定通信,解决了传统Http通信带来的请求延迟高,数据量大导致堵塞等等问题。本文模拟需求为持续监控XX数据(从后端某请求获取),并传递给前端,每隔10秒进行一次更新。
-
代码部分
后端
1.引入依赖
在对应模块的pom.xml下引入websocket依赖
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.创建启动配置WebSocketConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* websocket 配置
*
*/
@Configuration
@EnableWebSocket
public class WebSocketConfig
{
@Bean
public ServerEndpointExporter serverEndpointExporter()
{
return new ServerEndpointExporter();
}
}
默认写法,不需要修改,@Bean代表项目启动时自动启动,使用了@EnableWebSocket注解,若未指定端口,则websocket将从服务器默认端口中发出,取决于项目的application.yml
server:
# 服务器的HTTP端口,默认为8080
port: 8888
3.创建服务配置WebSocketServer.java
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint(value = "/webSocket")
@Component
public class WebSocketServer {
private static Map<String , Session> clientMap = new ConcurrentHashMap<>();
/**
* 客户端与服务端连接成功
* @param session
*/
@OnOpen
public void onOpen(Session session){
System.out.println("ws连接成功");
clientMap.put(session.getId(),session);
}
/**
* 客户端与服务端连接关闭
* @param session
*/
@OnClose
public void onClose(Session session){
clientMap.remove(session.getId());
}
/**
* 客户端与服务端连接异常
* @param error
* @param session
*/
@OnError
public void onError(Throwable error,Session session) {
error.printStackTrace();
}
/**
* 客户端向服务端发送消息
* @param message 传递信息
*/
@OnMessage
public void onMsg(String message) {
System.out.println("收到前端消息:"+message);
//以下为模拟发送消息
sendMessage();
}
/**
* 定时向客户端发送数据(10秒间隔)
*/
@Scheduled(cron = "0/10 * * * * ?")
private void sendMessage(){
//获得Map的Key的集合
Set<String> sessionIdSet = clientMap.keySet();
// 此处相当于一个广播操作//迭代Key集合
for (String sessionId : sessionIdSet) {
//根据Key得到value
Session session = clientMap.get(sessionId);
//发送消息给客户端,每10s给前端推送数据
session.getAsyncRemote().sendText("我是后端发来的数据");
}
}
}
此java类主要存放ws各类行为触发方法,如onOpen则为客户端连接ws成功的触发器,onClose为关闭连接等等,他们通过@OnOpen、@OnClose注解绑定。
onMsg则为客户端向服务端发送消息的触发,可以在此处写一些内容或直接调用sendMessage()向客户端回复消息。
最后比较重要的,sendMessage方法,则可以直接向客户端(前端)发送内容,客户端通过回调函数可以直接获取该内容,从而在页面中显示。此处使用了定时器,实现了每隔n秒进行一次发送行为。
4.配置匿名访问
配置该内容,可以使websocket连接跳过安全策略,实现不登录访问
在SecurityConfig.java下配置如下内容
// 如果需要不登录也可以访问,需要在`SecurityConfig.java`中设置匿名访问
("/websocket").permitAll()
注:若在客户端连接ws时,连接失败且报code:200错误时,可能是因为此步没有配置成功
前端
1.创建webSocket.js文件
export default {
// 初始化webSocket
webSocketInit(webSocketURL) {
// webSocketURL为ws地址,如ws://127.0.0.1:8080/websocket
this.webSocket = new WebSocket(webSocketURL)
this.webSocket.onopen = this.onOpenwellback
this.webSocket.onmessage = this.onMessageCallback
this.webSocket.onerror = this.onErrorCallback
this.webSocket.onclose = this.onCloseCallback
},
// 自定义回调函数
setOpenCallback(callback) { // 与服务端连接打开回调函数
this.webSocket.onopen = callback
},
setMessageCallback (callback) { // 与服务端发送消息回调函数
this.webSocket.onmessage = callback
},
setErrorCallback (callback) { // 与服务端连接异常回调函数
this.webSocket.onerror = callback
},
setCloseCallback (callback) { // 与服务端连接关闭回调函数
this.webSocket.onclose = callback
},
close () { // 关闭连接
this.webSocket.close()
},
sendMessage (message) { // 发送消息函数
this.webSocket.send(message)
},
}
2.在业务中使用
import webSocket from "@/api/system/webSocket";
// 连接webSocket
connectWs() {
webSocket.webSocketInit("ws://localhost:8888/webSocket");
webSocket.setOpenCallback((res) => {
console.log("建立连接成功", res);
});
webSocket.setMessageCallback((res) => {
console.log("发送消息成功", res);
});
webSocket.setErrorCallback((res) => {
console.log("接收失败消息", res);
});
webSocket.setCloseCallback((res) => {
console.log("连接关闭", res);
});
webSocket.setCloseCallback((res) => {
console.log("连接关闭", res);
});
},
// 向ws服务端发送消息
sendMessage() {
// 使用webSocket交互
webSocket.sendMessage("手动发消息");
},
//关闭websocket连接(若后台依然有定时任务,建议使用http的方式删除后台的定时任务执行)
closeMessage() {
webSocket.close();
},
其中的webSocket.webSocketInit("ws://localhost:8888/webSocket"),ws请求地址根据情况填写,下方的各种回调函数在对应的ws行为触发时就会被调用,在此写自己的业务即可。
-
功能验证
1.连接
连接成功后,可以在浏览器的F12中,看到打印信息
在“网络”中可以查看到连接
2.接收信息(后端->前端)
收到服务器发来的一条数据后,会在控制台打印
或者在网络->消息中查看
3.发送信息(前端->后端)
向服务端发送消息,可以在服务器的运行终端看到打印的信息