修复用户应用键的分隔符,从 '-' 更改为 '--',以保持一致性并优化 WebSocket 连接管理

This commit is contained in:
2026-02-05 14:08:45 +08:00
parent bf436f05e3
commit 5200cf4c38
4 changed files with 31 additions and 12 deletions

View File

@@ -3,11 +3,11 @@ export const createStudioAppListHtml = (opts: StudioOpts) => {
const user = opts.user!; const user = opts.user!;
const userAppKey = opts?.userAppKey; const userAppKey = opts?.userAppKey;
let showUserAppKey = userAppKey; let showUserAppKey = userAppKey;
if (showUserAppKey && showUserAppKey.startsWith(user + '-')) { if (showUserAppKey && showUserAppKey.startsWith(user + '--')) {
showUserAppKey = showUserAppKey.replace(user + '-', ''); showUserAppKey = showUserAppKey.replace(user + '--', '');
} }
const pathApps = opts?.appIds?.map(appId => { const pathApps = opts?.appIds?.map(appId => {
const shortAppId = appId.replace(opts!.user + '-', '') const shortAppId = appId.replace(opts!.user + '--', '')
return { return {
appId, appId,
shortAppId, shortAppId,

View File

@@ -20,7 +20,7 @@ export const wssFun: WebSocketListenerFun = async (req, res) => {
return; return;
} }
const user = loginUser?.tokenUser?.username; const user = loginUser?.tokenUser?.username;
const userApp = user + '-' + id; const userApp = user + '--' + id;
logger.debug('注册 ws 连接', userApp); logger.debug('注册 ws 连接', userApp);
const wsMessage = wsProxyManager.get(userApp); const wsMessage = wsProxyManager.get(userApp);
if (wsMessage) { if (wsMessage) {

View File

@@ -2,6 +2,7 @@ import { nanoid } from 'nanoid';
import { WebSocket } from 'ws'; import { WebSocket } from 'ws';
import { logger } from '../logger.ts'; import { logger } from '../logger.ts';
import { EventEmitter } from 'eventemitter3'; import { EventEmitter } from 'eventemitter3';
import { set } from 'zod';
class WsMessage { class WsMessage {
ws: WebSocket; ws: WebSocket;
@@ -82,7 +83,13 @@ type WssMessageOptions = {
}; };
export class WsProxyManager { export class WsProxyManager {
wssMap: Map<string, WsMessage> = new Map(); wssMap: Map<string, WsMessage> = new Map();
constructor() { } PING_INTERVAL = 30000; // 30 秒检查一次连接状态
constructor(opts?: { pingInterval?: number }) {
if (opts?.pingInterval) {
this.PING_INTERVAL = opts.pingInterval;
}
this.checkConnceted();
}
register(id: string, opts?: { ws: WebSocket; user: string }) { register(id: string, opts?: { ws: WebSocket; user: string }) {
if (this.wssMap.has(id)) { if (this.wssMap.has(id)) {
const value = this.wssMap.get(id); const value = this.wssMap.get(id);
@@ -91,7 +98,7 @@ export class WsProxyManager {
value.destroy(); value.destroy();
} }
} }
const [username, appId] = id.split('-'); const [username, appId] = id.split('--');
const url = new URL(`/${username}/v1/${appId}`, 'https://kevisual.cn/'); const url = new URL(`/${username}/v1/${appId}`, 'https://kevisual.cn/');
console.log('WsProxyManager register', id, '访问地址', url.toString()); console.log('WsProxyManager register', id, '访问地址', url.toString());
const value = new WsMessage({ ws: opts?.ws, user: opts?.user }); const value = new WsMessage({ ws: opts?.ws, user: opts?.user });
@@ -114,4 +121,16 @@ export class WsProxyManager {
get(id: string) { get(id: string) {
return this.wssMap.get(id); return this.wssMap.get(id);
} }
checkConnceted() {
const that = this;
setTimeout(() => {
that.wssMap.forEach((value, key) => {
if (value.ws.readyState !== WebSocket.OPEN) {
logger.debug('ws not connected, unregister', key);
that.unregister(key);
}
});
that.checkConnceted();
}, this.PING_INTERVAL);
}
} }

View File

@@ -32,7 +32,7 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt
if (!userAppKey) { if (!userAppKey) {
if (isAdmin) { if (isAdmin) {
// 获取所有的管理员的应用列表 // 获取所有的管理员的应用列表
const ids = wsProxyManager.getIds(user + '-'); const ids = wsProxyManager.getIds(user + '--');
const html = createStudioAppListHtml({ user, appIds: ids, userAppKey }); const html = createStudioAppListHtml({ user, appIds: ids, userAppKey });
res.writeHead(200, { 'Content-Type': 'text/html' }); res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(html); res.end(html);
@@ -42,8 +42,8 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt
return false; return false;
} }
} }
if (!userAppKey.includes('-')) { if (!userAppKey.includes('--')) {
userAppKey = user + '-' + userAppKey; userAppKey = user + '--' + userAppKey;
} }
// TODO: 如果不是管理员,是否需要添加其他人可以访问的逻辑? // TODO: 如果不是管理员,是否需要添加其他人可以访问的逻辑?
@@ -51,12 +51,12 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt
opts?.createNotFoundPage?.('没有访问应用权限'); opts?.createNotFoundPage?.('没有访问应用权限');
return false; return false;
} }
if (!userAppKey.startsWith(user + '-')) { if (!userAppKey.startsWith(user + '--')) {
userAppKey = user + '-' + userAppKey; userAppKey = user + '--' + userAppKey;
} }
logger.debug('data', data); logger.debug('data', data);
const client = wsProxyManager.get(userAppKey); const client = wsProxyManager.get(userAppKey);
const ids = wsProxyManager.getIds(user + '-'); const ids = wsProxyManager.getIds(user + '--');
if (!client) { if (!client) {
if (isAdmin) { if (isAdmin) {
const html = createStudioAppListHtml({ user, appIds: ids, userAppKey }); const html = createStudioAppListHtml({ user, appIds: ids, userAppKey });