From 172bf00d9371c9d5b2acc350249f398489339494 Mon Sep 17 00:00:00 2001 From: landaiqing <3517283258@qq.com> Date: Fri, 27 Sep 2024 00:42:50 +0800 Subject: [PATCH] :art: organize websocket code structure --- .env.development | 3 +- .env.production | 2 +- src/store/index.ts | 2 ++ src/store/modules/websocketStore.ts | 45 +++++++++++++++++++++++++++++ src/utils/websocket/websocket.ts | 28 +++--------------- src/views/Main/MainPage.vue | 24 +++++++++++++-- src/views/QRLogin/QRLogin.vue | 14 ++++----- 7 files changed, 80 insertions(+), 38 deletions(-) create mode 100644 src/store/modules/websocketStore.ts diff --git a/.env.development b/.env.development index fa6edb7..5336f65 100644 --- a/.env.development +++ b/.env.development @@ -16,5 +16,4 @@ VITE_TITLE_NAME='五味子云相册' VITE_APP_TOKEN_KEY='Bearer' # the websocket url -#VITE_WEB_SOCKET_URL='ws://127.0.0.1:80/api/ws/gws' -VITE_WEB_SOCKET_URL='wss://landaiqing.cn/api/ws/gws' +VITE_WEB_SOCKET_URL='ws://127.0.0.1:80/api/ws/gws' diff --git a/.env.production b/.env.production index 0528b20..6d04ae7 100644 --- a/.env.production +++ b/.env.production @@ -7,7 +7,7 @@ VITE_APP_BASE_API='/sys' VITE_APP_TITLE=生产环境 # 网络请求公用地址 -VITE_API_BASE_URL='http://127.0.0.1:80' +VITE_API_BASE_URL='https://landaiqing.cn' VITE_TITLE_NAME='五味子云相册' diff --git a/src/store/index.ts b/src/store/index.ts index b364885..32bd7c0 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -3,6 +3,7 @@ import {useThemeStore} from "@/store/modules/themeStore.ts"; import {langStore} from "@/store/modules/langStore.ts"; import {useClientStore} from "@/store/modules/clientStore.ts"; import {useCommentStore} from "@/store/modules/commentStore.ts"; +import {useWebSocketStore} from "@/store/modules/websocketStore.ts"; export default function useStore() { return { @@ -11,5 +12,6 @@ export default function useStore() { lang: langStore(), client: useClientStore(), comment: useCommentStore(), + websocket: useWebSocketStore(), }; } diff --git a/src/store/modules/websocketStore.ts b/src/store/modules/websocketStore.ts new file mode 100644 index 0000000..b66b513 --- /dev/null +++ b/src/store/modules/websocketStore.ts @@ -0,0 +1,45 @@ +// useWebSocketStore.ts +import {defineStore} from 'pinia'; +import {onUnmounted, reactive} from 'vue'; +import {WebSocketService} from '@/utils/websocket/websocket.ts'; + +type MessageCallback = (data: any) => void; +type EventCallback = () => void; +export const useWebSocketStore = defineStore('websocket', () => { + const state = reactive({ + wsService: null as WebSocketService | null, + }); + + function initialize(options: { url: string; protocols?: string | string[]; reconnectTimeout?: number }) { + state.wsService = new WebSocketService(options); + state.wsService.open(); + + onUnmounted(() => { + state.wsService?.close(true); + }); + } + + function sendMessage(data: any) { + state.wsService?.send(data); + } + + function on(event: 'message', callback: MessageCallback) { + state.wsService?.on(event, callback); + } + + function onEvent(event: 'open' | 'error' | 'close', callback: EventCallback) { + state.wsService?.on(event, callback); + } + + function close() { + state.wsService?.close(); + } + + return { + initialize, + sendMessage, + on, + onEvent, + close, + }; +}); diff --git a/src/utils/websocket/websocket.ts b/src/utils/websocket/websocket.ts index b801a3b..8cf6f1c 100644 --- a/src/utils/websocket/websocket.ts +++ b/src/utils/websocket/websocket.ts @@ -1,6 +1,4 @@ -// src/utils/websocket.ts -import {onUnmounted} from 'vue'; - +// WebSocketService.ts interface WebSocketOptions { url: string; protocols?: string | string[]; @@ -10,14 +8,13 @@ interface WebSocketOptions { type MessageCallback = (data: any) => void; type EventCallback = () => void; -class WebSocketService { +export class WebSocketService { private ws: WebSocket | null = null; private callbacks: { [key: string]: (MessageCallback | EventCallback)[] } = {}; private reconnectTimeoutMs: number = 5000; // 默认5秒重连间隔 private heartbeatIntervalMs: number = 5000; // 默认5秒心跳间隔 - constructor(private options: WebSocketOptions) { - } + constructor(private options: WebSocketOptions) {} public open(): void { this.ws = new WebSocket(this.options.url, this.options.protocols); @@ -25,6 +22,7 @@ class WebSocketService { this.ws.addEventListener('message', this.handleMessage); this.ws.addEventListener('error', this.handleError); this.ws.addEventListener('close', this.handleClose); + setInterval(() => { if (this.ws && this.ws.readyState === WebSocket.OPEN) { this.send("ping"); @@ -55,7 +53,6 @@ class WebSocketService { } private handleOpen = (): void => { - console.log('WebSocket连接已建立'); if (this.callbacks.open) { this.callbacks.open.forEach((cb) => (cb as EventCallback)()); } @@ -63,7 +60,6 @@ class WebSocketService { private handleMessage = (event: MessageEvent): void => { const data = JSON.parse(event.data); - console.log('WebSocket接收到消息:', data); if (this.callbacks.message) { this.callbacks.message.forEach((cb) => (cb as MessageCallback)(data)); } @@ -94,19 +90,3 @@ class WebSocketService { } } } - -export default function useWebSocket(options: WebSocketOptions) { - const wsService = new WebSocketService(options); - - onUnmounted(() => { - wsService.close(true); - }); - - return { - open: wsService.open.bind(wsService), - close: wsService.close.bind(wsService), - reconnect: wsService.reconnect.bind(wsService), - on: wsService.on.bind(wsService), - send: wsService.send.bind(wsService) - }; -} diff --git a/src/views/Main/MainPage.vue b/src/views/Main/MainPage.vue index d227675..57295b1 100644 --- a/src/views/Main/MainPage.vue +++ b/src/views/Main/MainPage.vue @@ -11,17 +11,37 @@ import {useRequest} from "alova/client"; import {getUserPermissions} from "@/api/user"; import useStore from "@/store"; import CommentReply from "@/components/CommentReply/index.vue"; +import {h, onMounted} from "vue"; +import {notification} from "ant-design-vue"; +import {SmileOutlined} from "@ant-design/icons-vue"; - +const websocket = useStore().websocket; +const userInfo = useStore().user; const {data, send} = useRequest(getUserPermissions, { immediate: false }); const handleClick = () => { - const userInfo = useStore().user; + const userId: string = userInfo.user.uid; send(userId); }; +const wsOptions = { + url: import.meta.env.VITE_WEB_SOCKET_URL + "?client_id=" + userInfo.user.uid, +}; + +onMounted(() => { + websocket.initialize(wsOptions); + websocket.on("message", async (data: any) => { + notification.open({ + message: '消息来了', + description: + data, + icon: () => h(SmileOutlined, {style: 'color: #108ee9'}), + }); + }); +}); +