springboot+vue+websocket 实现消息推送
项目要做一个实时消息的功能,类似下图的功能。右上角的数字需要实时改变;思路大概有几种(可能也有别的我没想到的,请不要纠结这个)。1.前端轮询调用,2.后台实时推送
在我一通百度之后,由于轮询调用比较耗资源,决定使用websocket来实现。(websocket有兼容性问题,IE10以上的浏览器一般是可以兼容的)
后台代码
1.在pom.xml文件中添加websocket依赖
<!-- 长连接 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.添加配置类 WebSocketConfig
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;
@EnableWebSocket
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3.添加websocket接收和发送消息的代码
import org.springframework.stereotype.Controller;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
@Controller
@ServerEndpoint("/websocket/{tableId}")
public class WebSocket {
private Session session;
private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();
private static Map<String,Session> sessionPool = new HashMap<>();
/**
* 打开新的连接
*/
@OnOpen
public void onOpen(Session session, @PathParam(value="tableId")String code) {
this.session = session;
webSockets.add(this);
sessionPool.put(code, session);
System.out.println("【websocket消息】有新的连接,总数为:"+webSockets.size());
}
@OnClose
public void onClose() {
webSockets.remove(this);
System.out.println("【websocket消息】连接断开,总数为:"+webSockets.size());
}
@OnMessage
public void onMessage(String message) {
System.out.println("【websocket消息】收到客户端消息:"+message);
}
// 此为广播消息
public void sendAllMessage(String message) {
for(WebSocket webSocket : webSockets) {
// System.out.println("群发 【websocket消息】广播消息:"+message);
try {
webSocket.session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 此为单点消息
public void sendOneMessage(String code, String message) {
Session session = sessionPool.get(code);
// System.out.println("单点消息 【websocket消息】 唯一标识" +code);
// 在发送数据之前先确认 session是否已经打开 使用session.isOpen() 为true 则发送消息
if (session != null && session.isOpen()) {
try {
// System.out.println("单点消息 【websocket消息】广播消息:" + message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
4.消息推送调用代码
@Autowired
private WebSocket webSocket;
// code:websocket唯一标识,message:推送的消息
// 单点消息调用
webSocket.sendOneMessage(code, message);
// 群发调用
webSocket.sendAllMessage(message);
前端vue代码
<el-badge :value="value" :max="100" class="item" ref="badge">
<div class="el-icon-chat-line-square"></div>
</el-badge>
created() {
this.initWebSocket();
},
destroyed () {
// 离开路由之后断开websocket连接
this.websock.close()
},
methods: {
initWebSocket () {
// 初始化weosocket
var host = window.location.host;
// userId 为websocket消息的唯一标识
this.websock = new WebSocket('ws://' + host + ':6700/websocket/'+ userId)
this.websock.onmessage = this.websocketonmessage
this.websock.onerror = this.websocketonerror
this.websock.onopen = this.websocketonopen
this.websock.onclose = this.websocketclose
},
websocketonopen () {
// 连接建立之后执行send方法发送数据
console.log("WebSocket连接成功");
},
websocketonerror () {
console.log( 'WebSocket连接失败')
},
websocketonmessage (e) {
// 数据接收
//将接受到的字符串数据转换成Json数据 根据业务看是否需要转换
var message = eval('(' + e.data + ')');
console.log(message);
this.value = message.count;
},
websocketsend (Data) {
// 数据发送
this.websock.send(Data)
},
websocketclose (e) {
// 关闭
console.log('已关闭连接', e)
}
}
测试工具
这个网址是下面参考博客里面的,我感觉挺好用的
http://ws.douqq.com/
参考博客:
https://www.cnblogs.com/lwx521/p/14086949.html
https://segmentfault.com/a/1190000017268973
https://blog.csdn.net/dhj393338/article/details/104637810