mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-02-04 06:31:13 +00:00
Refactor DebugAdapter to extend IOB11NetworkAdapter
Refactored DebugAdapter to inherit from IOB11NetworkAdapter, improving integration with the OneBot network manager. Enhanced WebSocket client management, error handling, and adapter lifecycle. Updated API and WebSocket handlers for better type safety and reliability. This change prepares the debug adapter for more robust and maintainable debugging sessions.
This commit is contained in:
parent
0f9647bf64
commit
772f07c58b
@ -1,11 +1,20 @@
|
||||
import { Router, Request, Response } from 'express';
|
||||
import { WebSocket, WebSocketServer } from 'ws';
|
||||
import { WebSocket, WebSocketServer, RawData } from 'ws';
|
||||
import { sendError, sendSuccess } from '@/napcat-webui-backend/src/utils/response';
|
||||
import { WebUiDataRuntime } from '@/napcat-webui-backend/src/helper/Data';
|
||||
import { IncomingMessage } from 'http';
|
||||
import { OB11Response } from '@/napcat-onebot/action/OneBotAction';
|
||||
import { ActionName } from '@/napcat-onebot/action/router';
|
||||
import { OB11LifeCycleEvent, LifeCycleSubType } from '@/napcat-onebot/event/meta/OB11LifeCycleEvent';
|
||||
import { IOB11NetworkAdapter } from '@/napcat-onebot/network/adapter';
|
||||
import { WebsocketServerConfig } from '@/napcat-onebot/config/config';
|
||||
import { ActionMap } from '@/napcat-onebot/action';
|
||||
import { NapCatCore } from '@/napcat-core/index';
|
||||
import { NapCatOneBot11Adapter } from '@/napcat-onebot/index';
|
||||
import { OB11EmitEventContent, OB11NetworkReloadType } from '@/napcat-onebot/network/index';
|
||||
import json5 from 'json5';
|
||||
|
||||
type ActionNameType = typeof ActionName[keyof typeof ActionName];
|
||||
|
||||
const router = Router();
|
||||
const DEFAULT_ADAPTER_NAME = 'debug-primary';
|
||||
@ -14,218 +23,205 @@ const DEFAULT_ADAPTER_NAME = 'debug-primary';
|
||||
* 统一的调试适配器
|
||||
* 用于注入到 OneBot NetworkManager,接收所有事件并转发给 WebSocket 客户端
|
||||
*/
|
||||
class DebugAdapter {
|
||||
name: string;
|
||||
isEnable: boolean = true;
|
||||
// 安全令牌
|
||||
class DebugAdapter extends IOB11NetworkAdapter<WebsocketServerConfig> {
|
||||
readonly token: string;
|
||||
|
||||
// 添加 config 属性,模拟 PluginConfig 结构
|
||||
config: {
|
||||
enable: boolean;
|
||||
name: string;
|
||||
messagePostFormat?: string;
|
||||
reportSelfMessage?: boolean;
|
||||
debug?: boolean;
|
||||
token?: string;
|
||||
heartInterval?: number;
|
||||
};
|
||||
wsClients: Set<WebSocket> = new Set();
|
||||
wsClients: WebSocket[] = [];
|
||||
wsClientWithEvent: WebSocket[] = [];
|
||||
lastActivityTime: number = Date.now();
|
||||
inactivityTimer: NodeJS.Timeout | null = null;
|
||||
readonly INACTIVITY_TIMEOUT = 5 * 60 * 1000; // 5分钟不活跃
|
||||
|
||||
constructor (sessionId: string) {
|
||||
this.name = `debug-${sessionId}`;
|
||||
// 生成简单的随机 token
|
||||
this.token = Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2);
|
||||
override get isActive (): boolean {
|
||||
return this.isEnable && this.wsClientWithEvent.length > 0;
|
||||
}
|
||||
|
||||
this.config = {
|
||||
constructor (sessionId: string, core: NapCatCore, obContext: NapCatOneBot11Adapter, actions: ActionMap) {
|
||||
const config: WebsocketServerConfig = {
|
||||
enable: true,
|
||||
name: this.name,
|
||||
name: `debug-${sessionId}`,
|
||||
host: '127.0.0.1',
|
||||
port: 0,
|
||||
messagePostFormat: 'array',
|
||||
reportSelfMessage: true,
|
||||
token: '',
|
||||
enableForcePushEvent: true,
|
||||
debug: true,
|
||||
token: this.token,
|
||||
heartInterval: 30000
|
||||
heartInterval: 0
|
||||
};
|
||||
|
||||
super(`debug-${sessionId}`, config, core, obContext, actions);
|
||||
this.token = Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2);
|
||||
this.isEnable = false;
|
||||
this.startInactivityCheck();
|
||||
}
|
||||
|
||||
// 实现 IOB11NetworkAdapter 接口所需的抽象方法
|
||||
async open (): Promise<void> { }
|
||||
async close (): Promise<void> { this.cleanup(); }
|
||||
async reload (_config: any): Promise<any> { return 0; }
|
||||
|
||||
/**
|
||||
* OneBot 事件回调 - 转发给所有 WebSocket 客户端 (原始流)
|
||||
*/
|
||||
async onEvent (event: any) {
|
||||
this.updateActivity();
|
||||
|
||||
const payload = JSON.stringify(event);
|
||||
|
||||
if (this.wsClients.size === 0) {
|
||||
async open (): Promise<void> {
|
||||
if (this.isEnable) {
|
||||
this.logger.logError('[Debug] Cannot open an already opened adapter');
|
||||
return;
|
||||
}
|
||||
|
||||
this.wsClients.forEach((client) => {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
client.send(payload);
|
||||
} catch (error) {
|
||||
console.error('[Debug] 发送事件到 WebSocket 失败:', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.logger.log('[Debug] Adapter opened:', this.name);
|
||||
this.isEnable = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用 OneBot API (HTTP 接口使用)
|
||||
*/
|
||||
async callApi (actionName: string, params: any): Promise<any> {
|
||||
this.updateActivity();
|
||||
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (!oneBotContext) {
|
||||
throw new Error('OneBot 未初始化');
|
||||
}
|
||||
|
||||
const action = oneBotContext.actions.get(actionName);
|
||||
if (!action) {
|
||||
throw new Error(`不支持的 API: ${actionName}`);
|
||||
}
|
||||
|
||||
return await action.handle(params, this.name, {
|
||||
name: this.name,
|
||||
enable: true,
|
||||
messagePostFormat: 'array',
|
||||
reportSelfMessage: true,
|
||||
debug: true,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理 WebSocket 消息 (OneBot 标准)
|
||||
*/
|
||||
async handleWsMessage (ws: WebSocket, message: string | Buffer) {
|
||||
this.updateActivity();
|
||||
let receiveData: { action: typeof ActionName[keyof typeof ActionName], params?: any, echo?: any; } = { action: ActionName.Unknown, params: {} };
|
||||
let echo;
|
||||
|
||||
try {
|
||||
receiveData = JSON.parse(message.toString());
|
||||
echo = receiveData.echo;
|
||||
} catch {
|
||||
this.sendWsResponse(ws, OB11Response.error('json解析失败,请检查数据格式', 1400, echo));
|
||||
async close (): Promise<void> {
|
||||
if (!this.isEnable) {
|
||||
return;
|
||||
}
|
||||
this.logger.log('[Debug] Adapter closing:', this.name);
|
||||
this.isEnable = false;
|
||||
|
||||
receiveData.params = (receiveData?.params) ? receiveData.params : {};
|
||||
|
||||
// 兼容 WebUI 之前可能的一些非标准格式 (如果用户是旧前端)
|
||||
// 但既然用户说要"原始流",我们优先支持标准格式
|
||||
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (!oneBotContext) {
|
||||
this.sendWsResponse(ws, OB11Response.error('OneBot 未初始化', 1404, echo));
|
||||
return;
|
||||
}
|
||||
|
||||
const action = oneBotContext.actions.get(receiveData.action as any);
|
||||
if (!action) {
|
||||
this.sendWsResponse(ws, OB11Response.error('不支持的API ' + receiveData.action, 1404, echo));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const retdata = await action.websocketHandle(receiveData.params, echo ?? '', this.name, this.config, {
|
||||
send: async (data: object) => {
|
||||
this.sendWsResponse(ws, OB11Response.ok(data, echo ?? '', true));
|
||||
},
|
||||
});
|
||||
this.sendWsResponse(ws, retdata);
|
||||
} catch (e: any) {
|
||||
this.sendWsResponse(ws, OB11Response.error(e.message || '内部错误', 1200, echo));
|
||||
}
|
||||
}
|
||||
|
||||
sendWsResponse (ws: WebSocket, data: any) {
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
ws.send(JSON.stringify(data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 WebSocket 客户端
|
||||
*/
|
||||
addWsClient (ws: WebSocket) {
|
||||
this.wsClients.add(ws);
|
||||
this.updateActivity();
|
||||
|
||||
// 发送生命周期事件 (Connect)
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (oneBotContext && oneBotContext.core) {
|
||||
try {
|
||||
const event = new OB11LifeCycleEvent(oneBotContext.core, LifeCycleSubType.CONNECT);
|
||||
ws.send(JSON.stringify(event));
|
||||
} catch (e) {
|
||||
console.error('[Debug] 发送生命周期事件失败', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除 WebSocket 客户端
|
||||
*/
|
||||
removeWsClient (ws: WebSocket) {
|
||||
this.wsClients.delete(ws);
|
||||
}
|
||||
|
||||
updateActivity () {
|
||||
this.lastActivityTime = Date.now();
|
||||
}
|
||||
|
||||
startInactivityCheck () {
|
||||
this.inactivityTimer = setInterval(() => {
|
||||
const inactive = Date.now() - this.lastActivityTime;
|
||||
// 如果没有 WebSocket 连接且超时,则自动清理
|
||||
if (inactive > this.INACTIVITY_TIMEOUT && this.wsClients.size === 0) {
|
||||
console.log(`[Debug] Adapter ${this.name} 不活跃,自动关闭`);
|
||||
this.cleanup();
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
cleanup () {
|
||||
// 停止不活跃检查定时器
|
||||
if (this.inactivityTimer) {
|
||||
clearInterval(this.inactivityTimer);
|
||||
this.inactivityTimer = null;
|
||||
}
|
||||
|
||||
// 关闭所有 WebSocket 连接
|
||||
// 关闭所有 WebSocket 连接并移除事件监听器
|
||||
this.wsClients.forEach((client) => {
|
||||
try {
|
||||
client.removeAllListeners();
|
||||
client.close();
|
||||
} catch (error) {
|
||||
// ignore
|
||||
this.logger.logError('[Debug] 关闭 WebSocket 失败:', error);
|
||||
}
|
||||
});
|
||||
this.wsClients.clear();
|
||||
|
||||
// 从 OneBot NetworkManager 移除
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (oneBotContext) {
|
||||
oneBotContext.networkManager.adapters.delete(this.name);
|
||||
}
|
||||
|
||||
// 从管理器中移除
|
||||
debugAdapterManager.removeAdapter(this.name);
|
||||
this.wsClients = [];
|
||||
this.wsClientWithEvent = [];
|
||||
}
|
||||
|
||||
async reload (_config: unknown): Promise<OB11NetworkReloadType> {
|
||||
return OB11NetworkReloadType.NetWorkReload;
|
||||
}
|
||||
|
||||
async onEvent<T extends OB11EmitEventContent> (event: T): Promise<void> {
|
||||
this.updateActivity();
|
||||
|
||||
const payload = JSON.stringify(event);
|
||||
this.wsClientWithEvent.forEach((wsClient) => {
|
||||
if (wsClient.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
wsClient.send(payload);
|
||||
} catch (error) {
|
||||
this.logger.logError('[Debug] 发送事件失败:', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async callApi (actionName: ActionNameType, params: Record<string, unknown>): Promise<unknown> {
|
||||
this.updateActivity();
|
||||
|
||||
const action = this.actions.get(actionName as Parameters<typeof this.actions.get>[0]);
|
||||
if (!action) {
|
||||
throw new Error(`不支持的 API: ${actionName}`);
|
||||
}
|
||||
|
||||
type ActionHandler = { handle: (params: unknown, ...args: unknown[]) => Promise<unknown>; };
|
||||
return await (action as ActionHandler).handle(params, this.name, this.config);
|
||||
}
|
||||
|
||||
private async handleMessage (wsClient: WebSocket, message: RawData): Promise<void> {
|
||||
this.updateActivity();
|
||||
let receiveData: { action: ActionNameType, params?: Record<string, unknown>, echo?: unknown; } = {
|
||||
action: ActionName.Unknown,
|
||||
params: {}
|
||||
};
|
||||
let echo: unknown = undefined;
|
||||
|
||||
try {
|
||||
receiveData = json5.parse(message.toString());
|
||||
echo = receiveData.echo;
|
||||
} catch {
|
||||
this.sendToClient(wsClient, OB11Response.error('json解析失败,请检查数据格式', 1400, echo));
|
||||
return;
|
||||
}
|
||||
|
||||
receiveData.params = receiveData?.params || {};
|
||||
|
||||
const action = this.actions.get(receiveData.action as Parameters<typeof this.actions.get>[0]);
|
||||
if (!action) {
|
||||
this.logger.logError('[Debug] 不支持的API:', receiveData.action);
|
||||
this.sendToClient(wsClient, OB11Response.error('不支持的API ' + receiveData.action, 1404, echo));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
type ActionHandler = { websocketHandle: (params: unknown, ...args: unknown[]) => Promise<unknown>; };
|
||||
const retdata = await (action as ActionHandler).websocketHandle(receiveData.params, echo ?? '', this.name, this.config, {
|
||||
send: async (data: object) => {
|
||||
this.sendToClient(wsClient, OB11Response.ok(data, echo ?? '', true));
|
||||
},
|
||||
});
|
||||
this.sendToClient(wsClient, retdata);
|
||||
} catch (e: unknown) {
|
||||
const error = e as Error;
|
||||
this.logger.logError('[Debug] 处理消息失败:', error);
|
||||
this.sendToClient(wsClient, OB11Response.error(error.message || '内部错误', 1200, echo));
|
||||
}
|
||||
}
|
||||
|
||||
private sendToClient (wsClient: WebSocket, data: unknown): void {
|
||||
if (wsClient.readyState === WebSocket.OPEN) {
|
||||
try {
|
||||
wsClient.send(JSON.stringify(data));
|
||||
} catch (error) {
|
||||
this.logger.logError('[Debug] 发送消息失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async addWsClient (ws: WebSocket): Promise<void> {
|
||||
this.wsClientWithEvent.push(ws);
|
||||
this.wsClients.push(ws);
|
||||
this.updateActivity();
|
||||
|
||||
// 发送连接事件
|
||||
this.sendToClient(ws, new OB11LifeCycleEvent(this.core, LifeCycleSubType.CONNECT));
|
||||
|
||||
ws.on('error', (err) => this.logger.log('[Debug] WebSocket Error:', err.message));
|
||||
ws.on('message', (message) => {
|
||||
this.handleMessage(ws, message).catch((e: unknown) => {
|
||||
this.logger.logError('[Debug] handleMessage error:', e);
|
||||
});
|
||||
});
|
||||
ws.on('ping', () => ws.pong());
|
||||
ws.once('close', () => this.removeWsClient(ws));
|
||||
}
|
||||
|
||||
private removeWsClient (ws: WebSocket): void {
|
||||
const normalIndex = this.wsClients.indexOf(ws);
|
||||
if (normalIndex !== -1) {
|
||||
this.wsClients.splice(normalIndex, 1);
|
||||
}
|
||||
const eventIndex = this.wsClientWithEvent.indexOf(ws);
|
||||
if (eventIndex !== -1) {
|
||||
this.wsClientWithEvent.splice(eventIndex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
updateActivity (): void {
|
||||
this.lastActivityTime = Date.now();
|
||||
}
|
||||
|
||||
startInactivityCheck (): void {
|
||||
this.inactivityTimer = setInterval(() => {
|
||||
const inactive = Date.now() - this.lastActivityTime;
|
||||
if (inactive > this.INACTIVITY_TIMEOUT && this.wsClients.length === 0) {
|
||||
this.logger.log(`[Debug] Adapter ${this.name} 不活跃,自动关闭`);
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (oneBotContext) {
|
||||
// 先从管理器移除,避免重复销毁
|
||||
debugAdapterManager.removeAdapter(this.name);
|
||||
// 使用 NetworkManager 标准流程关闭
|
||||
oneBotContext.networkManager.closeSomeAdapters([this]).catch((e: unknown) => {
|
||||
this.logger.logError('[Debug] 自动关闭适配器失败:', e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证 Token
|
||||
*/
|
||||
validateToken (inputToken: string): boolean {
|
||||
return this.token === inputToken;
|
||||
}
|
||||
@ -244,17 +240,20 @@ class DebugAdapterManager {
|
||||
return this.currentAdapter;
|
||||
}
|
||||
|
||||
// 获取 OneBot 上下文
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (!oneBotContext) {
|
||||
throw new Error('OneBot 未初始化,无法创建调试适配器');
|
||||
}
|
||||
|
||||
// 创建新实例
|
||||
const adapter = new DebugAdapter('primary');
|
||||
const adapter = new DebugAdapter('primary', oneBotContext.core, oneBotContext, oneBotContext.actions);
|
||||
this.currentAdapter = adapter;
|
||||
|
||||
// 注册到 OneBot NetworkManager
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (oneBotContext) {
|
||||
oneBotContext.networkManager.adapters.set(adapter.name, adapter as any);
|
||||
} else {
|
||||
console.warn('[Debug] OneBot 未初始化,无法注册适配器');
|
||||
}
|
||||
// 使用 NetworkManager 标准流程注册并打开适配器
|
||||
oneBotContext.networkManager.registerAdapterAndOpen(adapter).catch((e: unknown) => {
|
||||
console.error('[Debug] 注册适配器失败:', e);
|
||||
});
|
||||
|
||||
return adapter;
|
||||
}
|
||||
@ -286,8 +285,9 @@ router.post('/create', async (_req: Request, res: Response) => {
|
||||
token: adapter.token,
|
||||
message: '调试适配器已就绪',
|
||||
});
|
||||
} catch (error: any) {
|
||||
sendError(res, error.message);
|
||||
} catch (error: unknown) {
|
||||
const err = error as Error;
|
||||
sendError(res, err.message);
|
||||
}
|
||||
});
|
||||
|
||||
@ -310,10 +310,11 @@ const handleCallApi = async (req: Request, res: Response) => {
|
||||
}
|
||||
|
||||
const { action, params } = req.body;
|
||||
const result = await adapter.callApi(action, params || {});
|
||||
const result = await adapter.callApi(action as ActionNameType, params || {});
|
||||
sendSuccess(res, result);
|
||||
} catch (error: any) {
|
||||
sendError(res, error.message);
|
||||
} catch (error: unknown) {
|
||||
const err = error as Error;
|
||||
sendError(res, err.message);
|
||||
}
|
||||
};
|
||||
|
||||
@ -329,10 +330,25 @@ router.post('/close/:adapterName', async (req: Request, res: Response) => {
|
||||
if (!adapterName) {
|
||||
return sendError(res, '缺少 adapterName 参数');
|
||||
}
|
||||
|
||||
const adapter = debugAdapterManager.getAdapter(adapterName);
|
||||
if (!adapter) {
|
||||
return sendError(res, '调试适配器不存在');
|
||||
}
|
||||
|
||||
// 先从管理器移除,避免重复销毁
|
||||
debugAdapterManager.removeAdapter(adapterName);
|
||||
|
||||
// 使用 NetworkManager 标准流程关闭适配器
|
||||
const oneBotContext = WebUiDataRuntime.getOneBotContext();
|
||||
if (oneBotContext) {
|
||||
await oneBotContext.networkManager.closeSomeAdapters([adapter]);
|
||||
}
|
||||
|
||||
sendSuccess(res, { message: '调试适配器已关闭' });
|
||||
} catch (error: any) {
|
||||
sendError(res, error.message);
|
||||
} catch (error: unknown) {
|
||||
const err = error as Error;
|
||||
sendError(res, err.message);
|
||||
}
|
||||
});
|
||||
|
||||
@ -340,7 +356,7 @@ router.post('/close/:adapterName', async (req: Request, res: Response) => {
|
||||
* WebSocket 连接处理
|
||||
* 路径: /api/Debug/ws?adapterName=xxx&token=xxx
|
||||
*/
|
||||
export function handleDebugWebSocket (request: IncomingMessage, socket: any, head: any) {
|
||||
export function handleDebugWebSocket (request: IncomingMessage, socket: unknown, head: unknown) {
|
||||
const url = new URL(request.url || '', `http://${request.headers.host}`);
|
||||
let adapterName = url.searchParams.get('adapterName');
|
||||
const token = url.searchParams.get('token') || url.searchParams.get('access_token');
|
||||
@ -353,8 +369,8 @@ export function handleDebugWebSocket (request: IncomingMessage, socket: any, hea
|
||||
// Debug session should provide token
|
||||
if (!token) {
|
||||
console.log('[Debug] WebSocket 连接被拒绝: 缺少 Token');
|
||||
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
|
||||
socket.destroy();
|
||||
(socket as { write: (data: string) => void; destroy: () => void; }).write('HTTP/1.1 401 Unauthorized\r\n\r\n');
|
||||
(socket as { destroy: () => void; }).destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -362,43 +378,37 @@ export function handleDebugWebSocket (request: IncomingMessage, socket: any, hea
|
||||
|
||||
// 如果是默认 adapter 且不存在,尝试创建
|
||||
if (!adapter && adapterName === DEFAULT_ADAPTER_NAME) {
|
||||
adapter = debugAdapterManager.getOrCreateAdapter();
|
||||
try {
|
||||
adapter = debugAdapterManager.getOrCreateAdapter();
|
||||
} catch (error) {
|
||||
console.log('[Debug] WebSocket 连接被拒绝: 无法创建适配器', error);
|
||||
(socket as { write: (data: string) => void; destroy: () => void; }).write('HTTP/1.1 500 Internal Server Error\r\n\r\n');
|
||||
(socket as { destroy: () => void; }).destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!adapter) {
|
||||
console.log('[Debug] WebSocket 连接被拒绝: 适配器不存在');
|
||||
socket.write('HTTP/1.1 404 Not Found\r\n\r\n');
|
||||
socket.destroy();
|
||||
(socket as { write: (data: string) => void; destroy: () => void; }).write('HTTP/1.1 404 Not Found\r\n\r\n');
|
||||
(socket as { destroy: () => void; }).destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!adapter.validateToken(token)) {
|
||||
console.log('[Debug] WebSocket 连接被拒绝: Token 无效');
|
||||
socket.write('HTTP/1.1 403 Forbidden\r\n\r\n');
|
||||
socket.destroy();
|
||||
(socket as { write: (data: string) => void; destroy: () => void; }).write('HTTP/1.1 403 Forbidden\r\n\r\n');
|
||||
(socket as { destroy: () => void; }).destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建 WebSocket 服务器
|
||||
const wsServer = new WebSocketServer({ noServer: true });
|
||||
|
||||
wsServer.handleUpgrade(request, socket, head, (ws) => {
|
||||
adapter.addWsClient(ws);
|
||||
|
||||
ws.on('message', async (data) => {
|
||||
try {
|
||||
await adapter.handleWsMessage(ws, data as any);
|
||||
} catch (error: any) {
|
||||
console.error('[Debug] handleWsMessage error', error);
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
adapter.removeWsClient(ws);
|
||||
});
|
||||
|
||||
ws.on('error', () => {
|
||||
adapter.removeWsClient(ws);
|
||||
wsServer.handleUpgrade(request, socket as never, head as Buffer, (ws) => {
|
||||
adapter.addWsClient(ws).catch((e: unknown) => {
|
||||
console.error('[Debug] 添加 WebSocket 客户端失败:', e);
|
||||
ws.close();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user