diff --git a/src/modules/html/studio-app-list/index.ts b/src/modules/html/studio-app-list/index.ts index 364ea31..3a7cd0d 100644 --- a/src/modules/html/studio-app-list/index.ts +++ b/src/modules/html/studio-app-list/index.ts @@ -3,11 +3,11 @@ export const createStudioAppListHtml = (opts: StudioOpts) => { const user = opts.user!; const userAppKey = opts?.userAppKey; let showUserAppKey = userAppKey; - if (showUserAppKey && showUserAppKey.startsWith(user + '-')) { - showUserAppKey = showUserAppKey.replace(user + '-', ''); + if (showUserAppKey && showUserAppKey.startsWith(user + '--')) { + showUserAppKey = showUserAppKey.replace(user + '--', ''); } const pathApps = opts?.appIds?.map(appId => { - const shortAppId = appId.replace(opts!.user + '-', '') + const shortAppId = appId.replace(opts!.user + '--', '') return { appId, shortAppId, diff --git a/src/modules/ws-proxy/index.ts b/src/modules/ws-proxy/index.ts index 4b886e8..f545aee 100644 --- a/src/modules/ws-proxy/index.ts +++ b/src/modules/ws-proxy/index.ts @@ -20,7 +20,7 @@ export const wssFun: WebSocketListenerFun = async (req, res) => { return; } const user = loginUser?.tokenUser?.username; - const userApp = user + '-' + id; + const userApp = user + '--' + id; logger.debug('注册 ws 连接', userApp); const wsMessage = wsProxyManager.get(userApp); if (wsMessage) { diff --git a/src/modules/ws-proxy/manager.ts b/src/modules/ws-proxy/manager.ts index 1c706f8..3997bc9 100644 --- a/src/modules/ws-proxy/manager.ts +++ b/src/modules/ws-proxy/manager.ts @@ -2,6 +2,7 @@ import { nanoid } from 'nanoid'; import { WebSocket } from 'ws'; import { logger } from '../logger.ts'; import { EventEmitter } from 'eventemitter3'; +import { set } from 'zod'; class WsMessage { ws: WebSocket; @@ -82,7 +83,13 @@ type WssMessageOptions = { }; export class WsProxyManager { wssMap: Map = 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 }) { if (this.wssMap.has(id)) { const value = this.wssMap.get(id); @@ -91,7 +98,7 @@ export class WsProxyManager { value.destroy(); } } - const [username, appId] = id.split('-'); + const [username, appId] = id.split('--'); const url = new URL(`/${username}/v1/${appId}`, 'https://kevisual.cn/'); console.log('WsProxyManager register', id, '访问地址', url.toString()); const value = new WsMessage({ ws: opts?.ws, user: opts?.user }); @@ -114,4 +121,16 @@ export class WsProxyManager { get(id: string) { 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); + } } diff --git a/src/modules/ws-proxy/proxy.ts b/src/modules/ws-proxy/proxy.ts index 82f428f..823f3e6 100644 --- a/src/modules/ws-proxy/proxy.ts +++ b/src/modules/ws-proxy/proxy.ts @@ -32,7 +32,7 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt if (!userAppKey) { if (isAdmin) { // 获取所有的管理员的应用列表 - const ids = wsProxyManager.getIds(user + '-'); + const ids = wsProxyManager.getIds(user + '--'); const html = createStudioAppListHtml({ user, appIds: ids, userAppKey }); res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(html); @@ -42,8 +42,8 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt return false; } } - if (!userAppKey.includes('-')) { - userAppKey = user + '-' + userAppKey; + if (!userAppKey.includes('--')) { + userAppKey = user + '--' + userAppKey; } // TODO: 如果不是管理员,是否需要添加其他人可以访问的逻辑? @@ -51,12 +51,12 @@ export const UserV1Proxy = async (req: IncomingMessage, res: ServerResponse, opt opts?.createNotFoundPage?.('没有访问应用权限'); return false; } - if (!userAppKey.startsWith(user + '-')) { - userAppKey = user + '-' + userAppKey; + if (!userAppKey.startsWith(user + '--')) { + userAppKey = user + '--' + userAppKey; } logger.debug('data', data); const client = wsProxyManager.get(userAppKey); - const ids = wsProxyManager.getIds(user + '-'); + const ids = wsProxyManager.getIds(user + '--'); if (!client) { if (isAdmin) { const html = createStudioAppListHtml({ user, appIds: ids, userAppKey });