🎨 organize websocket code structure
This commit is contained in:
@@ -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'
|
||||
|
@@ -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='五味子云相册'
|
||||
|
||||
|
@@ -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(),
|
||||
};
|
||||
}
|
||||
|
45
src/store/modules/websocketStore.ts
Normal file
45
src/store/modules/websocketStore.ts
Normal file
@@ -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,
|
||||
};
|
||||
});
|
@@ -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)
|
||||
};
|
||||
}
|
||||
|
@@ -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'}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
|
@@ -58,9 +58,9 @@ import BoxDog from "@/components/BoxDog/BoxDog.vue";
|
||||
import QRLoginFooter from "@/views/QRLogin/QRLoginFooter.vue";
|
||||
import {useRouter} from 'vue-router';
|
||||
import {generateQrCode} from "@/api/oauth/wechat.ts";
|
||||
import {onMounted, onUnmounted, ref} from "vue";
|
||||
import {onMounted, ref} from "vue";
|
||||
import logo from "@/assets/svgs/logo-schisandra.svg";
|
||||
import useWebSocket from "@/utils/websocket/websocket.ts";
|
||||
|
||||
import useStore from "@/store";
|
||||
import {message} from "ant-design-vue";
|
||||
import {generateClientId, getUserDevice} from "@/api/oauth";
|
||||
@@ -71,6 +71,7 @@ const router = useRouter();
|
||||
const client = useStore().client;
|
||||
const qrcode = ref<string>('');
|
||||
const status = ref<string>('loading');
|
||||
const websocket = useStore().websocket;
|
||||
|
||||
/**
|
||||
* 获取client_id
|
||||
@@ -119,15 +120,14 @@ const wsOptions = {
|
||||
url: import.meta.env.VITE_WEB_SOCKET_URL + "?client_id=" + getLocalClientId(),
|
||||
};
|
||||
|
||||
const {open, close, on} = useWebSocket(wsOptions);
|
||||
|
||||
/**
|
||||
* 监听消息
|
||||
*/
|
||||
async function handleListenMessage() {
|
||||
open();
|
||||
websocket.initialize(wsOptions);
|
||||
// 注册消息接收处理函数
|
||||
on('message', async (data: any) => {
|
||||
websocket.on('message', async (data: any) => {
|
||||
if (data.code === 200 && data.data) {
|
||||
const user = useStore().user;
|
||||
const {access_token, refresh_token, uid, expires_at} = data.data;
|
||||
@@ -148,10 +148,6 @@ async function handleListenMessage() {
|
||||
onMounted(async () => {
|
||||
await getQrCode();
|
||||
});
|
||||
|
||||
onUnmounted(async () => {
|
||||
close(true);
|
||||
});
|
||||
</script>
|
||||
<style src="./index.scss" scoped>
|
||||
@import "@/assets/styles/global.scss";
|
||||
|
Reference in New Issue
Block a user