feat: enhance WebSocket proxy with user connection management and status reporting
- Updated StudioOpts type to include infoList for user connection status. - Added rendering of connection info in createStudioAppListHtml. - Modified self-restart logic to use a specific app path. - Improved WebSocket connection handling in wsProxyManager, including user registration and ID management. - Implemented connection status checks and responses in UserV1Proxy. - Introduced renderServerHtml function to inject server data into HTML responses. - Refactored page-proxy request handling for better URL management.
This commit is contained in:
@@ -3,46 +3,40 @@ import { getLoginUserByToken } from '@/modules/auth.ts';
|
||||
import { logger } from '../logger.ts';
|
||||
export const wsProxyManager = new WsProxyManager();
|
||||
import { WebSocketListenerFun } from '@kevisual/router/src/server/server-type.ts'
|
||||
// 生成一个随机六位字符串作为注册 ID
|
||||
const generateRegistryId = () => {
|
||||
return Math.random().toString(36).substring(2, 8);
|
||||
}
|
||||
export const wssFun: WebSocketListenerFun = async (req, res) => {
|
||||
// do nothing, just to enable ws upgrade event
|
||||
const { id, ws, token, data, emitter } = req;
|
||||
// console.log('req', req)
|
||||
const { type } = data || {};
|
||||
|
||||
if (type === 'registryClient') {
|
||||
const loginUser = await getLoginUserByToken(token);
|
||||
if (!loginUser?.tokenUser) {
|
||||
logger.debug('未登录,断开连接');
|
||||
ws.send(JSON.stringify({ code: 401, message: '未登录' }));
|
||||
setTimeout(() => {
|
||||
ws.close(401, 'Unauthorized');
|
||||
}, 1000);
|
||||
let isLogin = false;
|
||||
let user = '';
|
||||
if (loginUser?.tokenUser) {
|
||||
isLogin = true;
|
||||
user = loginUser?.tokenUser?.username;
|
||||
} else {
|
||||
logger.debug('未登录,请求等待用户验证', data);
|
||||
user = data?.username || '';
|
||||
}
|
||||
if (!user) {
|
||||
logger.debug('未提供用户名,无法注册 ws 连接');
|
||||
ws.close();
|
||||
return;
|
||||
}
|
||||
const user = loginUser?.tokenUser?.username;
|
||||
const userApp = user + '--' + id;
|
||||
logger.debug('注册 ws 连接', userApp);
|
||||
const wsMessage = wsProxyManager.get(userApp);
|
||||
if (wsMessage) {
|
||||
logger.debug('ws 连接已存在,关闭旧连接', userApp);
|
||||
wsMessage.ws.close();
|
||||
wsProxyManager.unregister(userApp);
|
||||
await new Promise((resolve) => setTimeout(resolve, 200));
|
||||
let userApp = user + '--' + id;
|
||||
// TODO: 如果存在, 而且之前的那个关闭了,不需要验证,直接覆盖和复用.
|
||||
let wsConnect = await wsProxyManager.createNewConnection({ ws, user, userApp, isLogin });
|
||||
if (wsConnect.isNew) {
|
||||
logger.debug('新连接注册成功', userApp);
|
||||
}
|
||||
// @ts-ignore
|
||||
wsProxyManager.register(userApp, { user, ws });
|
||||
ws.send(
|
||||
JSON.stringify({
|
||||
type: 'connected',
|
||||
user: user,
|
||||
id,
|
||||
}),
|
||||
);
|
||||
emitter.once('close--' + id, () => {
|
||||
logger.debug('ws emitter closed');
|
||||
wsProxyManager.unregister(userApp);
|
||||
});
|
||||
// @ts-ignore
|
||||
ws.data.userApp = userApp;
|
||||
ws.data.userApp = wsConnect.id;
|
||||
return;
|
||||
}
|
||||
// @ts-ignore
|
||||
|
||||
Reference in New Issue
Block a user