src/App.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/components/bg-task/FYBgTaskCard.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/enum/socketMessage.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/socket/FYWebSocket.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/socket/index.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/socket/socketMessage.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/App.vue
@@ -40,8 +40,6 @@ <script> import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; import { FYWebSocket } from '@/socket/index.js' import eventBus from '@/socket/eventBus.js'; export default { data() { return { @@ -58,25 +56,6 @@ navPage(titles) { this.navTitles = titles; }, // è¿æ¥websocket connectWebSocket() { this.socket = new FYWebSocket() this.socket.init({ time: 4 * 1000, timeout: 2 * 1000, reconnect: 3 * 1000 }, true) }, // æçº¿éè¿websocket startReconnectWebSocket() { eventBus.register('reconnect', () => { this.connectWebSocket() }) } }, created() { this.connectWebSocket() this.startReconnectWebSocket() } }; </script> src/components/bg-task/FYBgTaskCard.vue
@@ -46,6 +46,7 @@ import { useFetchData } from '@/composables/fetchData'; import bgtaskApi from '@/api/fysp/bgtaskApi'; import { enumBgTask, BG_TASK_TYPE, BG_TASK_STATUS } from '@/enum/bgTask'; import eventBus from '@/socket/eventBus.js'; export default { setup() { @@ -77,6 +78,32 @@ } }, methods: { registerBgTaskMessage() { eventBus.register('background_task', (data) => { this.refreshTaskById(data) }) }, /** * å·æ°ä¸ä¸ªä»»å¡éè¿idï¼å¦ææ¯æ°çä»»å¡åæ·»å å°ä»»å¡å表taskListä¸ * @param data */ refreshTaskById(data) { if (!data || data == {}) { return; } let isNewTask = true for (let index = 0; index < this.taskList.length; index++) { const task = this.taskList[index]; if (task.id == data.id) { this.taskList[index] = data isNewTask = false break } } if (isNewTask) { this.taskList.push(data) } }, addTask() {}, newTestTask() { this.fetchData((page, pageSize) => { @@ -151,7 +178,11 @@ }, gotoResult(index) {} }, created() { this.registerBgTaskMessage() }, mounted() { bgtaskApi.newTestTask(1) this.fetchTask(); // setInterval(() => { // this.fetchTask(); src/enum/socketMessage.js
@@ -1,6 +1,17 @@ const messageTypes = [ { id: 0, label: 'å¿è·³æ£æµ', value: '0' }, { id: 1, label: 'åå°ä»»å¡', value: '1' }, { id: 2, label: 'ä¸å¡æ¥å¿', value: '2' } { id: 0, value: '0', label: 'å¿è·³æºå¶', name: 'heartbeat' }, { id: 1, value: '1', label: 'åå°ä»»å¡', name: 'background_task' }, { id: 2, value: '2', label: 'ä¸å¡æ¥å¿', name: 'business_log' } ]; export { messageTypes }; /** * æ ¹æ®socketæ¶æ¯ç±»ååæ®µå¾å°è¿ä¸ªç±»å对象 * @param {*} value socketæ¶æ¯ç±»å * @returns 对åºçæ¶æ¯ç±»å对象 */ function getByValue(value) { return messageTypes.find((v) => v.value == value); } function isHeartbeatMessageByType(type) { return type == '0'; } export { messageTypes, getByValue, isHeartbeatMessageByType }; src/main.js
@@ -5,6 +5,7 @@ import { router } from './router'; import App from './App.vue'; import timeUtil from './utils/time-util'; import { initSocketClient } from '@/socket/index.js' // import 'element-plus/dist/index.css'; import './assets/main.css'; @@ -19,6 +20,9 @@ import isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; // socket客æ·ç«¯ initSocketClient() dayjs.extend(isSameOrAfter); dayjs.extend(isSameOrBefore); src/socket/FYWebSocket.js
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,134 @@ import eventBus from './eventBus.js'; import { messageTypes, getByValue, isHeartbeatMessageByType } from '@/enum/socketMessage.js'; import { encodeMessage, decodeMessage } from './socketMessage.js'; import { $socket_base_url } from '@/api/index.js'; class FYWebSocket extends WebSocket { constructor() { super($socket_base_url); return this; } /** * heartBeatConfig å¿è·³è¿æ¥åæ° * time: å¿è·³æ¶é´é´é * timeout: å¿è·³è¶ æ¶é´é * reconnect: æçº¿éè¿æ¶é´é´é * isReconnect æ¯å¦æçº¿éè¿ */ init(heartBeatConfig, isReconnect) { this.onopen = this.openHandler; // è¿æ¥æååçåè°å½æ° this.onclose = this.closeHandler; // è¿æ¥å ³éåçåè° å½æ° this.onmessage = this.messageHandler; // æ¶å°æå¡å¨æ°æ®åçåè°å½æ° this.onerror = this.errorHandler; // è¿æ¥åçé误çåè°æ¹æ³ this.heartBeatConfig = heartBeatConfig; // å¿è·³è¿æ¥é ç½®åæ° this.isReconnect = isReconnect; // è®°å½æ¯å¦æçº¿éè¿ this.reconnectTimer = null; // è®°å½æçº¿éè¿çæ¶é´å¨ this.startHeartBeatTimer = null; // è®°å½å¿è·³æ¶é´å¨ this.webSocketState = false; // è®°å½socketè¿æ¥ç¶æ trueä¸ºå·²è¿æ¥ } // è·åæ¶æ¯ getMessage({ data }) { return decodeMessage(data); } // åéæ¶æ¯ sendMessage(type, data) { return this.send(encodeMessage(type, data)); } // è¿æ¥æååçåè°å½æ° openHandler() { console.log('====onopen è¿æ¥æå===='); // socketç¶æè®¾ç½®ä¸ºè¿æ¥ï¼å为åé¢çæçº¿éè¿çæ¦æªå¨ this.webSocketState = true; // 夿æ¯å¦å¯å¨å¿è·³æºå¶ if (this.heartBeatConfig && this.heartBeatConfig.time) { this.startHeartBeat(this.heartBeatConfig.time); } } // æ¶å°æå¡å¨æ°æ®åçåè°å½æ° messageHandler(res) { const webSocketMsg = this.getMessage(res); if (!(webSocketMsg && webSocketMsg != null && webSocketMsg != {})) { return; } console.log("webSocketMsg", webSocketMsg); const type = webSocketMsg.type; const data = webSocketMsg.data; let typeObj = getByValue(type); console.log("typeObj", typeObj); if (isHeartbeatMessageByType(type)) { // å°è¿æ¥ç¶ææ´æ°ä¸ºå¨çº¿ this.webSocketState = true; eventBus.emit(typeObj.name, data); console.log('====onmessage å¿è·³æ£æµ====', data); } else { // åéäºä»¶ eventBus.emit(typeObj.name, data); console.log(`====onmessage ${typeObj.label}====`, data); } } // è¿æ¥å ³éåçåè° å½æ° closeHandler() { console.log('====onclose websocketå ³éè¿æ¥===='); // 设置socketç¶æä¸ºæçº¿ this.webSocketState = false; // 卿å¼è¿æ¥æ¶ æ¸ é¤å¿è·³æ¶é´å¨å æå¼éè¿æ¶é´å¨ this.startHeartBeatTimer && clearTimeout(this.startHeartBeatTimer); this.reconnectTimer && clearTimeout(this.reconnectTimer); this.reconnectWebSocket(); } errorHandler() { console.log('====onerror websocketè¿æ¥åºé===='); // 设置socketç¶æä¸ºæçº¿ this.webSocketState = false; // éæ°è¿æ¥ this.reconnectWebSocket(); } // å¿è·³åå§åæ¹æ³ timeï¼å¿è·³é´é startHeartBeat(time) { this.startHeartBeatTimer = setTimeout(() => { // 客æ·ç«¯æ¯é䏿®µæ¶é´åæå¡ç«¯åéä¸ä¸ªå¿è·³æ¶æ¯ this.sendMessage(messageTypes[0].value, Date.now()); this.waitingServer(); }, time); } //å¨å®¢æ·ç«¯åéæ¶æ¯ä¹åï¼å»¶æ¶çå¾ æå¡å¨ååº,éè¿webSocketState夿æ¯å¦è¿çº¿æå waitingServer() { this.webSocketState = false; setTimeout(() => { // è¿çº¿æåç¶æä¸ ç»§ç»å¿è·³æ£æµ if (this.webSocketState) { this.startHeartBeat(this.heartBeatConfig.time); return; } console.log('å¿è·³æ ååº, å·²ç»åæå¡ç«¯æçº¿'); // éæ°è¿æ¥æ¶ï¼è®°å¾è¦å å ³éå½åè¿æ¥ try { this.close(); } catch (error) { console.log('å½åè¿æ¥å·²ç»å ³é'); } // // éæ°è¿æ¥ // this.reconnectWebSocket() }, this.heartBeatConfig.timeout); } // éæ°è¿æ¥ reconnectWebSocket() { // 夿æ¯å¦æ¯éæ°è¿æ¥ç¶æ(å³è¢«å¨ç¶ææçº¿)ï¼å¦ææ¯ä¸»å¨æçº¿çä¸éè¦éæ°è¿æ¥ if (!this.isReconnect) { return; } // æ ¹æ®ä¼ å ¥çæçº¿éè¿æ¶é´é´é å»¶æ¶è¿æ¥ this.reconnectTimer = setTimeout(() => { // 触åéæ°è¿æ¥äºä»¶ eventBus.emit('reconnect'); }, this.heartBeatConfig.reconnect); } } export { FYWebSocket }; src/socket/index.js
@@ -1,134 +1,31 @@ import eventBus from './eventBus.js'; import { messageTypes } from '@/enum/socketMessage.js'; import { encodeMessage, decodeMessage } from './socketMessage.js'; import { $socket_base_url } from '@/api/index.js'; class FYWebSocket extends WebSocket { constructor() { super($socket_base_url); return this; } /** * heartBeatConfig å¿è·³è¿æ¥åæ° * time: å¿è·³æ¶é´é´é * timeout: å¿è·³è¶ æ¶é´é * reconnect: æçº¿éè¿æ¶é´é´é * isReconnect æ¯å¦æçº¿éè¿ */ init(heartBeatConfig, isReconnect) { this.onopen = this.openHandler; // è¿æ¥æååçåè°å½æ° this.onclose = this.closeHandler; // è¿æ¥å ³éåçåè° å½æ° this.onmessage = this.messageHandler; // æ¶å°æå¡å¨æ°æ®åçåè°å½æ° this.onerror = this.errorHandler; // è¿æ¥åçé误çåè°æ¹æ³ this.heartBeatConfig = heartBeatConfig; // å¿è·³è¿æ¥é ç½®åæ° this.isReconnect = isReconnect; // è®°å½æ¯å¦æçº¿éè¿ this.reconnectTimer = null; // è®°å½æçº¿éè¿çæ¶é´å¨ this.startHeartBeatTimer = null; // è®°å½å¿è·³æ¶é´å¨ this.webSocketState = false; // è®°å½socketè¿æ¥ç¶æ trueä¸ºå·²è¿æ¥ } // è·åæ¶æ¯ getMessage({ data }) { return decodeMessage(data); } // åéæ¶æ¯ sendMessage(type, data) { return this.send(encodeMessage(type, data)); } // è¿æ¥æååçåè°å½æ° openHandler() { console.log('====onopen è¿æ¥æå===='); // socketç¶æè®¾ç½®ä¸ºè¿æ¥ï¼å为åé¢çæçº¿éè¿çæ¦æªå¨ this.webSocketState = true; // 夿æ¯å¦å¯å¨å¿è·³æºå¶ if (this.heartBeatConfig && this.heartBeatConfig.time) { this.startHeartBeat(this.heartBeatConfig.time); } } // æ¶å°æå¡å¨æ°æ®åçåè°å½æ° messageHandler(res) { const webSocketMsg = this.getMessage(res); if (!(webSocketMsg && webSocketMsg != null && webSocketMsg != {})) { return; } const type = webSocketMsg.type; const data = webSocketMsg.data switch (type) { case '1': // åå°ä»»å¡ // åéäºä»¶ eventBus.emit('1', data); console.log('====onmessage åå°ä»»å¡====', data); break; case '2': // ä¸å¡æ¥å¿ // åéäºä»¶ eventBus.emit('2', data); console.log('====onmessage ä¸å¡æ¥å¿====', data); break; case '0': // å¿è·³æ£æµ // å°è¿æ¥ç¶ææ´æ°ä¸ºå¨çº¿ this.webSocketState = true; eventBus.emit('0', data); console.log('====onmessage å¿è·³æ£æµ====', data); break; } } // è¿æ¥å ³éåçåè° å½æ° closeHandler() { console.log('====onclose websocketå ³éè¿æ¥===='); // 设置socketç¶æä¸ºæçº¿ this.webSocketState = false; // 卿å¼è¿æ¥æ¶ æ¸ é¤å¿è·³æ¶é´å¨å æå¼éè¿æ¶é´å¨ this.startHeartBeatTimer && clearTimeout(this.startHeartBeatTimer); this.reconnectTimer && clearTimeout(this.reconnectTimer); this.reconnectWebSocket(); } errorHandler() { console.log('====onerror websocketè¿æ¥åºé===='); // 设置socketç¶æä¸ºæçº¿ this.webSocketState = false; // éæ°è¿æ¥ this.reconnectWebSocket(); } // å¿è·³åå§åæ¹æ³ timeï¼å¿è·³é´é startHeartBeat(time) { this.startHeartBeatTimer = setTimeout(() => { // 客æ·ç«¯æ¯é䏿®µæ¶é´åæå¡ç«¯åéä¸ä¸ªå¿è·³æ¶æ¯ this.sendMessage(messageTypes[0].value, Date.now()); this.waitingServer(); }, time); } //å¨å®¢æ·ç«¯åéæ¶æ¯ä¹åï¼å»¶æ¶çå¾ æå¡å¨ååº,éè¿webSocketState夿æ¯å¦è¿çº¿æå waitingServer() { this.webSocketState = false; setTimeout(() => { // è¿çº¿æåç¶æä¸ ç»§ç»å¿è·³æ£æµ if (this.webSocketState) { this.startHeartBeat(this.heartBeatConfig.time); return; } console.log('å¿è·³æ ååº, å·²ç»åæå¡ç«¯æçº¿'); // éæ°è¿æ¥æ¶ï¼è®°å¾è¦å å ³éå½åè¿æ¥ try { this.close(); } catch (error) { console.log('å½åè¿æ¥å·²ç»å ³é'); } // // éæ°è¿æ¥ // this.reconnectWebSocket() }, this.heartBeatConfig.timeout); } import { FYWebSocket } from '@/socket/FYWebSocket.js' import eventBus from '@/socket/eventBus.js'; // éæ°è¿æ¥ reconnectWebSocket() { // 夿æ¯å¦æ¯éæ°è¿æ¥ç¶æ(å³è¢«å¨ç¶ææçº¿)ï¼å¦ææ¯ä¸»å¨æçº¿çä¸éè¦éæ°è¿æ¥ if (!this.isReconnect) { return; } // æ ¹æ®ä¼ å ¥çæçº¿éè¿æ¶é´é´é å»¶æ¶è¿æ¥ this.reconnectTimer = setTimeout(() => { // 触åéæ°è¿æ¥äºä»¶ eventBus.emit('reconnect'); }, this.heartBeatConfig.reconnect); let socket = null; // è¿æ¥websocket function connectWebSocket() { if (socket == null) { socket = new FYWebSocket() } socket.init({ time: 4 * 1000, timeout: 2 * 1000, reconnect: 3 * 1000 }, true) return socket; } export { FYWebSocket }; // æçº¿éè¿websocket function startReconnectWebSocket() { eventBus.register('reconnect', () => { connectWebSocket() }) } /** * åå§åsocket客æ·ç«¯ */ function initSocketClient() { connectWebSocket(); startReconnectWebSocket(); } export { initSocketClient } src/socket/socketMessage.js
@@ -7,7 +7,7 @@ // ç»æç¬¦å· const endStr = '%%'; // æ ¡éªæ ¼å¼ function verificationMessahe(message) { function verificationMessage(message) { if (!message || message == '') { return false; } @@ -28,7 +28,7 @@ * @returns */ function decodeMessage(message) { if (!verificationMessahe(message)) { if (!verificationMessage(message)) { return; } const parts = message.slice(startStr.length, -endStr.length).split(splitStr); @@ -49,4 +49,4 @@ return `${startStr}${type}${splitStr}${JSON.stringify(data)}${endStr}`; } export { verificationMessahe, decodeMessage, encodeMessage, messageTypes }; export { verificationMessage, decodeMessage, encodeMessage };