feat: 更新WebSocket连接逻辑,支持动态用户ID和token传递

This commit is contained in:
zhanghao 2026-08-26 14:03:55 +08:00
parent fd98bda0eb
commit 5c2c8eca2d
2 changed files with 27 additions and 2 deletions

View File

@ -12,6 +12,7 @@ import '@/assets/styles/index.scss' // global css
import App from './App' import App from './App'
import store from './store' import store from './store'
import useUserStore from './store/modules/user'
import router from './router' import router from './router'
import directive from './directive' // directive import directive from './directive' // directive
import WebSocketPlugin from './plugins/websocket' import WebSocketPlugin from './plugins/websocket'
@ -92,7 +93,7 @@ app.use(plugins)
app.use(elementIcons) app.use(elementIcons)
app.use(WebSocketPlugin, { app.use(WebSocketPlugin, {
url: import.meta.env.VITE_WS_URL, url: import.meta.env.VITE_WS_URL,
userId: 'your_user_id' userId: () => useUserStore(store).id
}) })
app.component('svg-icon', SvgIcon) app.component('svg-icon', SvgIcon)

View File

@ -1,3 +1,5 @@
import { getToken } from '../utils/auth';
const MEDIA_HEADER_SIZE = 26; const MEDIA_HEADER_SIZE = 26;
const MEDIA_MAGIC = [0x43, 0x4d, 0x56, 0x46]; // CMVF const MEDIA_MAGIC = [0x43, 0x4d, 0x56, 0x46]; // CMVF
const MEDIA_MIME_TYPES = { const MEDIA_MIME_TYPES = {
@ -18,6 +20,11 @@ class WebSocketManager {
this.maxQueueSize = 100; this.maxQueueSize = 100;
this.status = false; this.status = false;
this.channelSubscriptions = new Set(); this.channelSubscriptions = new Set();
this.connectionUserId = null;
}
resolveUserId() {
return typeof this.userId === 'function' ? this.userId() : this.userId;
} }
connect() { connect() {
@ -25,8 +32,19 @@ class WebSocketManager {
console.error('浏览器不支持 WebSocket'); console.error('浏览器不支持 WebSocket');
return; return;
} }
if (!this.url) {
console.error('WebSocket 地址未配置');
return;
}
this.ws = new WebSocket(`${this.url}?userId=${this.userId}`, [], { perMessageDeflate: true }); const userId = this.resolveUserId();
if (typeof this.userId === 'function' && !userId) return;
const connectionUrl = new URL(this.url, window.location.href);
if (userId) connectionUrl.searchParams.set('userId', userId);
const token = getToken();
if (token) connectionUrl.searchParams.set('token', token);
this.connectionUserId = userId || null;
this.ws = new WebSocket(connectionUrl.toString(), [], { perMessageDeflate: true });
this.ws.binaryType = 'arraybuffer'; // 确保接收 ArrayBuffer this.ws.binaryType = 'arraybuffer'; // 确保接收 ArrayBuffer
this.ws.onopen = () => { this.ws.onopen = () => {
@ -168,6 +186,12 @@ class WebSocketManager {
this.channelSubscriptions.delete(payload.channel); this.channelSubscriptions.delete(payload.channel);
} }
} }
const userId = this.resolveUserId();
if (this.ws && this.ws.readyState !== WebSocket.CLOSED && this.connectionUserId !== userId) {
this.ws.close(4001, 'user identity changed');
return;
}
if (!this.ws || this.ws.readyState === WebSocket.CLOSED) this.connect();
if (this.ws && this.ws.readyState === 1) { if (this.ws && this.ws.readyState === 1) {
this.ws.send(JSON.stringify(payload)); this.ws.send(JSON.stringify(payload));
} else if (payload?.type !== 'channel_subscription') { } else if (payload?.type !== 'channel_subscription') {