/* eslint-disable no-console */
|
/* eslint-disable unicorn/prefer-add-event-listener */
|
import { ref } from 'vue';
|
|
import { useMessage } from '@jnpf/hooks';
|
|
import { useAppConfig } from '@vben/hooks';
|
import { useAccessStore, useUserStore } from '@vben/stores';
|
|
import ReconnectingWebSocket from 'reconnecting-websocket';
|
|
import { $t } from '#/locales';
|
import { useAuthStore } from '#/store';
|
import { getRealJnpfAppEnCode } from '#/utils/jnpf';
|
|
const userStore = useUserStore();
|
const userInfo = userStore.getUserInfo;
|
const { createMessage, createWarningModal } = useMessage();
|
const { isDevMode, webSocketURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
|
|
const url = isDevMode() ? `${webSocketURL}/api/message/websocket/` : webSocketURL ? `${webSocketURL}/websocket/` : `${window.location.origin}/websocket/`;
|
const webSocketUrl = url.replace('https://', 'wss://').replace('http://', 'ws://');
|
|
let ws: any;
|
const listeners = new Map();
|
|
export function useWebSocket() {
|
const accessStore = useAccessStore();
|
const authStore = useAuthStore();
|
const token = accessStore.accessToken;
|
const server = ref(webSocketUrl + encodeURIComponent(token as string));
|
/** 初始化WebSocket */
|
function initWebSocket() {
|
if (ws) {
|
ws.close();
|
ws = null;
|
}
|
ws = new ReconnectingWebSocket(server.value);
|
|
ws.addEventListener('open', onOpen);
|
ws.onerror = onError;
|
ws.onmessage = onMessage;
|
|
function onOpen() {
|
const onConnection = { method: 'OnConnection', mobileDevice: false, systemId: userInfo?.systemId, isSeparate: !!getRealJnpfAppEnCode() };
|
sendWsMsg(JSON.stringify(onConnection));
|
}
|
|
function onError(e) {
|
console.log('[WebSocket] 连接发生错误:', e);
|
}
|
|
function onMessage(res) {
|
if (res.data) {
|
try {
|
const dataStr = res.data;
|
const data = JSON.parse(dataStr);
|
for (const callback of listeners.keys()) {
|
try {
|
callback(data);
|
} catch (error) {
|
console.error(error);
|
}
|
}
|
// initMessage: //初始化
|
// sendMessage: //发送消息
|
// receiveMessage: //接收消息
|
// messageList: //消息列表
|
// messagePush: //消息推送
|
switch (data.method) {
|
// 断开websocket连接
|
case 'closeSocket': {
|
if (ws) {
|
ws.close();
|
ws = null;
|
}
|
break;
|
}
|
// 用户过期
|
case 'logout': {
|
if (data.token && data.token !== token) return location.reload();
|
if (ws) {
|
ws.close();
|
ws = null;
|
}
|
createMessage.error(data.msg || '登录过期,请重新登录').then(() => {
|
accessStore.setAccessToken(null);
|
authStore.logout();
|
});
|
break;
|
}
|
// 刷新页面
|
case 'refresh': {
|
createWarningModal({
|
title: $t('common.tipTitle'),
|
content: data.msg || '您的权限发生变更,请刷新界面!',
|
okText: '刷新',
|
onOk: () => {
|
location.reload();
|
},
|
});
|
break;
|
}
|
default: {
|
break;
|
}
|
}
|
} catch (error) {
|
console.error('[WebSocket] data解析失败:', error);
|
}
|
}
|
}
|
}
|
/**
|
* 添加 WebSocket 消息监听
|
* @param callback
|
*/
|
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
|
*/
|
function offWebSocket(callback: (data: object) => any) {
|
listeners.delete(callback);
|
}
|
|
function getWebSocket() {
|
return ws;
|
}
|
|
function sendWsMsg(msg: string) {
|
try {
|
const msgObj = JSON.parse(msg);
|
msgObj.token = token;
|
const content = JSON.stringify(msgObj);
|
ws.send(content);
|
} catch {}
|
}
|
|
function closeWebSocket() {
|
if (ws) {
|
ws.close();
|
ws = null;
|
}
|
}
|
|
return {
|
initWebSocket,
|
sendWsMsg,
|
onWebSocket,
|
offWebSocket,
|
getWebSocket,
|
closeWebSocket,
|
};
|
}
|