Springboot + Vue 最简集成websocket
配置类 WebSocketConfig。具体类 Websocket。
·
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
配置类 WebSocketConfig
@Configuration
@EnableWebSocket
public class WebSocketConfig {
/**
* 注入ServerEndpointExporter,
* 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
具体类 Websocket
@Slf4j
@Component
@ServerEndpoint("/websocket/{key}")
public class WebSocket {
private String key;
private Session session;
private static final AtomicInteger onlineCount = new AtomicInteger(0);
private static final ConcurrentHashMap<String, WebSocket> webSocketMap = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam(value = "key") String key) {
this.key = key;
this.session = session;
if (webSocketMap.containsKey(key)) {
log.info("【WebSocket】存在连接,已删除");
webSocketMap.remove(key);
webSocketMap.put(key, this);
} else {
webSocketMap.put(key, this);
onlineCount.getAndIncrement();
}
log.info("【WebSocket】有新的连接,连接密钥为: {},当前连接数: {}", key, onlineCount);
}
@OnClose
public void onClose(@PathParam("key") String key) {
if (webSocketMap.containsKey(key)) {
webSocketMap.remove(key);
onlineCount.getAndDecrement();
log.warn("【WebSocket】连接断开,断开密钥为: {},当前连接数: {}", key, onlineCount);
}
}
@OnError
public void onError(Session session, Throwable error) {
log.warn("【WebSocket】消息出现错误,错误密钥为: {},原因为: {}", key, error.getMessage());
error.printStackTrace();
}
@OnMessage
public void onMessage(String message, @PathParam(value = "key") String key) {
log.info("【WebSocket】收到客户端消息: {},消息密钥为: {}", message, key);
if (!StrUtil.isEmpty(message)) {
JSONObject js = new JSONObject();
js.put("key", key);
js.put("message", message);
log.info(js.toJSONString());
// TODO: 2022/12/25 收到消息处理
}
}
public void pushMessage(String key, String message) {
WebSocket webSocket = webSocketMap.get(key);
if (ObjUtil.isNotNull(webSocket)) {
Session session = webSocket.session;
if (ObjUtil.isNotNull(session) && session.isOpen()) {
try {
log.info("【WebSocket】 发送消息: {},密钥为: {}", message, key);
session.getBasicRemote().sendText(message);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
}
}
前端
- 安装vueuse
yarn add @vueuse/core
- 新建hook =》 useWebSocket.ts
import {unref} from 'vue';
import {useWebSocket, UseWebSocketReturn} from '@vueuse/core';
let result: UseWebSocketReturn<any>;
const listeners = new Map();
/**
* 开启 WebSocket 链接,全局只需执行一次
* @param url
*/
export function connectWebSocket(url: string) {
result = useWebSocket(url, {
// 自动重连 (遇到错误最多重复连接10次)
autoReconnect: {
retries: 10,
delay: 5000
},
});
if (result) {
result.open = onOpen;
result.close = onClose;
const ws = unref(result.ws);
if (ws != null) {
ws.onerror = onError;
ws.onmessage = onMessage;
}
}
}
function onOpen() {
console.log('[WebSocket] 连接成功');
}
// @ts-ignore
function onClose(e) {
console.log('[WebSocket] 连接断开:', e);
}
// @ts-ignore
function onError(e) {
console.log('[WebSocket] 连接发生错误: ', e);
}
function onMessage(e: MessageEvent) {
// console.info('[WebSocket] -----接收消息-------', e.data);
try {
const data = JSON.parse(e.data);
for (const callback of listeners.keys()) {
try {
callback(data);
} catch (err) {
console.error(err);
}
}
} catch (err) {
console.error('[WebSocket] data解析失败:', err);
}
}
/**
* 添加 WebSocket 消息监听
* @param callback
*/
export function onWebSocket(callback: (data: object) => any) {
if (!listeners.has(callback)) {
if (typeof callback === 'function') {
listeners.set(callback, null);
} else {
console.debug('[WebSocket] 添加 WebSocket 消息监听失败:传入的参数不是一个方法');
}
}
}
/**
* 解除 WebSocket 消息监听
*
* @param callback
*/
export function offWebSocket(callback: (data: object) => any) {
listeners.delete(callback);
}
export function useMyWebSocket() {
return result;
}
- 在需要使用的界面引入websocket
import {connectWebSocket, onWebSocket} from "@/hooks/useWebSocket";
- 连接初始化方法
onMounted(() => initWebSocket())
const initWebSocket = () => {
let key = 'call'
let url
if (import.meta.env.VITE_BASE_API.indexOf("/lysf6") != -1) {
url = 'ws://' + window.location.hostname + ':8081/lysf6/websocket/' + key
} else {
url = 'ws://' + window.location.hostname + ':4029/websocket/' + key;
}
connectWebSocket(url);
console.log('【WebSocket】连接: %s', url)
onWebSocket(onWebSocketMessage);
}
- 收到消息方法
function onWebSocketMessage(data: any) {
callLoading.value = false
callData.value = data
dataStore.setCurrentData(data)
showDetail.value = true
}
let timer: NodeJS.Timeout | null = null;
const callLoading = ref<boolean>(false);
const callDataHandler = async () => {
callLoading.value = true
await getCallData(sensorStore.currentCode)
timer = setTimeout(() => {
callLoading.value = false
}, 7000)
}
更多推荐
已为社区贡献1条内容
所有评论(0)