最近在项目中,使用到了WebSocket来实时推送服务器的数据到客户端,今天来记录总结一下。
想要使用WebSocket来实时推送数据,首先需要服务器与客户端直接建立连接,也就是握手(HTTP协议)
每5秒钟发生一个心跳
@Scheduled(cron = "0/5 * * * * ? ") public void sendHeart() { MessageWebSocket.broadcast(new WebSocketMessage(WebSocketMessage.CMD_HEART, "SUCCESS")); }
后端重要的代码:
ServerEndpoint("/ws/{userId}")
@Component
@Slf4j
public class MessageWebSocket {
/**
* concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象.
*/
private static Map<String, MessageWebSocket> mapUserId = new ConcurrentHashMap<>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据.
*/
private Session session;
/**
* 接收userId.
*/
private String userId = "";
/**
* . 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
this.session = session;
this.userId = userId;
mapUserId.put(userId, this);
log.info("用户连接:" + userId);
try {
send(JSON.toJSONString(new WebSocketMessage(WebSocketMessage.CMD_CONN, "SUCCESS")));
} catch (IOException e) {
e.printStackTrace();
log.error("用户:" + userId + ",网络异常!!!!!!");
}
}
/**
* . 连接关闭调用的方法
*/
@OnClose
public void onClose() {
mapUserId.remove(userId);
}
/**
* . 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("user id:" + userId + ",message:" + message);
}
/**
* .
*
* @param session 回话
* @param error 错误信息
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("user id:" + this.userId + ",reason:" + error.getMessage());
error.printStackTrace();
}
/**
* . 实现服务器主动推送
*/
public void send(String message) throws IOException {
if (this.session != null) {
synchronized (session) {
this.session.getBasicRemote().sendText(message);
}
}
}
/**
* . 实现服务器主动推送
*/
public static void send(String userId, String message) throws IOException {
MessageWebSocket socket = mapUserId.get(userId);
if (socket != null) {
try {
socket.send(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 广播发送.
*
* @param message webSocket消息
*/
public static void broadcast(WebSocketMessage message) {
if (null == message) {
return;
}
String content = JSON.toJSONString(message);
//log.info("message :{}", content);
for (String userId : mapUserId.keySet()) {
try {
send(userId, content);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
前端代码(VUE):百度搜索前端连接WebSocket
methods: {
initWebSocket() { //初始化weosocket
const wsuri = "ws://127.0.0.1:8080";
this.websock = new WebSocket(wsuri);
this.websock.onmessage = this.websocketonmessage;
this.websock.onopen = this.websocketonopen;
this.websock.onerror = this.websocketonerror;
this.websock.onclose = this.websocketclose;
},
websocketonopen() { //连接建立之后执行send方法发送数据
let actions = {
"test": "123"
};
this.websocketsend(JSON.stringify(actions));
},
websocketonerror() { //连接建立失败重连
this.initWebSocket();
},
websocketonmessage(e) { //数据接收
const redata = JSON.parse(e.data);
},
websocketsend(Data) { //数据发送
this.websock.send(Data);
},
websocketclose(e) { //关闭
console.log('断开连接', e);
},
}