欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > VUE使用websocket

VUE使用websocket

2024/10/24 16:32:41 来源:https://blog.csdn.net/w_t_y_y/article/details/141597226  浏览:    关键词:VUE使用websocket

在之前搭建好的项目的基础上新版security demo(二)前端-CSDN博客

目录

一、代码改造

1、后端改造

2、VUE使用websocket

3、测试

二、按用户推送

1、完整代码如下

1.1、前端

1.2、后端:

2、测试


一、代码改造

1、后端改造

(1)把websocket相关代码复制到web项目:

(2)添加白名单

web-socket端口无需token验证,SecurityWebConfig添加白名单

 @Beanpublic WebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().requestMatchers("/param/**", "/user-websocket-endpoint/**","/menu-websocket-endpoint/**");}
2、VUE使用websocket
<template><div>this is user manage</div>
</template>
<script>
export default {data() {return {socket: null,message: '',inputMessage: ''};},mounted() {// Create a new WebSocket connectionthis.socket = new WebSocket("ws://localhost:2222/securityDemo/user-websocket-endpoint");// Set up event listenersthis.socket.onopen = (event) => {console.log('WebSocket connection opened.');this.socket.send("Hello Server! This is menu client");};this.socket.onmessage = (event) => {this.message = event.data;};this.socket.onerror = (error) => {console.error('WebSocket Error:', error);};this.socket.onclose = (event) => {console.log('WebSocket connection closed.');};},methods: {sendMessage() {if (this.socket && this.inputMessage) {this.socket.send(this.inputMessage);this.inputMessage = ''; // Clear the input field after sending}}},// beforeDestroy() {//   // Close the WebSocket connection when the component is destroyed//   if (this.socket) {//     this.socket.close();//   }// }
};
</script>

menumanage.vue代码和这个类似。 

3、测试

分别启动前后端,打开浏览器

(1)查看消息收发

切换到菜单管理:

再次切换到user页面,会断开之前的连接重新建立连接,因为vue每次进入页面都会执行mounted。 

idea控制台打印:

(2)postman调用user发送消息接口

浏览器接收成功:

postman调用menu发送消息接口:

浏览器接收成功:

二、按用户推送

 上面的demo,所有的客户端都会接收到消息,现在希望推送给某个user。则需要建立WebSocketSession和userId的关系,

(1)前端在open建立连接时发送userId;

<!DOCTYPE html>
<html>
<head><title>WebSocket Client</title>
</head>
<body><script>const userId = "user123"; // Replace with dynamic user IDconst socket = new WebSocket(`ws://localhost:8080/websocket-endpoint`);socket.onopen = function(event) {console.log("WebSocket connection opened.");socket.send(JSON.stringify({ type: "REGISTER", userId: userId }));};socket.onmessage = function(event) {const message = event.data;console.log("Message from server: " + message);};socket.onclose = function(event) {console.log("WebSocket connection closed.");};socket.onerror = function(error) {console.error("WebSocket Error: " + error);};</script>
</body>
</html>

(2)后端WebSocketHandler存储userId和WebSocketSession的映射关系

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.socket.CloseStatus;
import org.springframework.stereotype.Component;import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;@Component
public class UserWebSocketHandler extends TextWebSocketHandler {private final ConcurrentMap<String, WebSocketSession> userSessions = new ConcurrentHashMap<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {String userId = getUserIdFromSession(session);if (userId != null) {userSessions.put(userId, session);System.out.println("WebSocket connection established for userId: " + userId);}}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {String userId = getUserIdFromSession(session);if (userId != null) {userSessions.remove(userId);System.out.println("WebSocket connection closed for userId: " + userId);}}public void sendMessageToUser(String userId, String message) throws IOException {WebSocketSession session = userSessions.get(userId);if (session != null && session.isOpen()) {session.sendMessage(new TextMessage(message));}}private String getUserIdFromSession(WebSocketSession session) {// Assuming userId is stored as a session attributereturn (String) session.getAttributes().get("userId");}
}

(3)发送消息时根据userId检索目标WebSocketSession。

1、完整代码如下
1.1、前端
<template><div>this is user manage:{{this.userAccount}}</div>
</template>
<script>
export default {data() {return {socket: null,message: '',inputMessage: ''};},
computed: {userAccount() {return this.$store.getters.name;}
},mounted() {// Create a new WebSocket connectionthis.socket = new WebSocket("ws://localhost:2222/securityDemo/user-websocket-endpoint");// Set up event listenersthis.socket.onopen = (event) => {console.log('WebSocket connection opened.');let msg = {"userAccount":this.userAccount}this.socket.send(JSON.stringify(msg));};this.socket.onmessage = (event) => {this.message = event.data;};this.socket.onerror = (error) => {console.error('WebSocket Error:', error);};this.socket.onclose = (event) => {console.log('WebSocket connection closed.');};},methods: {sendMessage() {if (this.socket && this.inputMessage) {this.socket.send(this.inputMessage);this.inputMessage = ''; // Clear the input field after sending}}},// beforeDestroy() {//   // Close the WebSocket connection when the component is destroyed//   if (this.socket) {//     this.socket.close();//   }// }
};
</script>
1.2、后端:

 (1)常量

package com.demo.security.ws.constant;import lombok.Getter;
import org.springframework.web.socket.WebSocketSession;import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;public class UserSessionConstant {@Getterprivate static Map<String,WebSocketSession> sessionMap = new HashMap<>();public static void add(String userId,WebSocketSession session) {sessionMap.put(userId,session);}public static void remove(WebSocketSession session) {//从map中找到key,再remove key//sessionMap.remove(userAccount);}
}

(2)ws操作

package com.demo.security.ws;import com.demo.security.dto.MsgDTO;
import com.demo.security.dto.UserDTO;
import com.demo.security.ws.constant.UserSessionConstant;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;import java.io.IOException;@Component
@Slf4j
public class UserWebSocketHandler extends TextWebSocketHandler {@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {//UserSessionConstant.add(session);log.info("user有新的连接,sessionId:{}",session.getId());}@Overridepublic void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// 处理接收到的消息log.info("user服务端Received message: {}",message.getPayload());String payLoad = message.getPayload();ObjectMapper objectMapper = new ObjectMapper();MsgDTO msgDTO = objectMapper.readValue(payLoad, MsgDTO.class);UserSessionConstant.add(msgDTO.getUserAccount(),session);}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {UserSessionConstant.remove(session);log.info("user连接已断开sessionId:{}",session.getId());}public void sendMessageToAll(String message) {for(WebSocketSession session : UserSessionConstant.getSessionMap().values()) {if (session.isOpen()) {try {session.sendMessage(new TextMessage(message));log.info("user发送消息给{}成功",session.getId());} catch (IOException e) {e.printStackTrace();}}}}public void sendMessageToUser(String message,String userAccount) {for(String sessionUserAccount : UserSessionConstant.getSessionMap().keySet()){if(!userAccount.equals(sessionUserAccount)){continue;}WebSocketSession session = UserSessionConstant.getSessionMap().get(userAccount);if (session.isOpen()) {try {session.sendMessage(new TextMessage(message));log.info("user发送消息给用户{}成功",userAccount);} catch (IOException e) {e.printStackTrace();}}}}
}

 (3)controller接口

package com.demo.security.controller;import com.demo.security.dto.UserDTO;
import com.demo.security.ws.UserWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/userMsg")
public class UserMsgController {@Autowiredprivate UserWebSocketHandler userWebSocketHandler;@RequestMapping("/send")public void sendMessage(UserDTO messageDTO) {userWebSocketHandler.sendMessageToUser(messageDTO.toString(),messageDTO.getUserAccount());}
}
2、测试

(1)

打开两个浏览器,分别登录zs、admin

后端断点可以看到map存储了两条数据:

(2)调用postman接口给zs发送消息:

查看浏览器,zs的账号接收到了消息,admin的没有接收到:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com