Improve Satori WebSocket logging and event handling

Enhanced debug logging in the Satori WebSocket server for better traceability of client events and authentication. Improved handling of client identification, including more robust checks and detailed logs for token validation. Removed unused MessageUnique logic from NapCatSatoriAdapter and added additional debug logs for event emission and message processing. Added a new onNtMsgSyncContactUnread method stub in NodeIKernelMsgListener.
This commit is contained in:
手瓜一十雪 2026-01-14 18:47:10 +08:00
parent b0d88d3705
commit 323dc71d4e
3 changed files with 46 additions and 20 deletions

View File

@ -382,5 +382,8 @@ export class NodeIKernelMsgListener {
// 第一次发现于Win 9.9.9-23159 // 第一次发现于Win 9.9.9-23159
onBroadcastHelperProgerssUpdate (..._args: unknown[]): any { onBroadcastHelperProgerssUpdate (..._args: unknown[]): any {
}
onNtMsgSyncContactUnread (..._args: unknown[]): any {
} }
} }

View File

@ -25,7 +25,7 @@ import {
ISatoriNetworkAdapter, ISatoriNetworkAdapter,
} from './network'; } from './network';
import { SatoriLoginStatus } from './types'; import { SatoriLoginStatus } from './types';
import { MessageUnique } from 'napcat-common/src/message-unique'; // import { MessageUnique } from 'napcat-common/src/message-unique';
import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler'; import { proxiedListenerOf } from '@/napcat-core/helper/proxy-handler';
import { WebUiDataRuntime } from 'napcat-webui-backend/src/helper/Data'; import { WebUiDataRuntime } from 'napcat-webui-backend/src/helper/Data';
@ -161,14 +161,12 @@ export class NapCatSatoriAdapter {
msgListener.onRecvMsg = async (msgs) => { msgListener.onRecvMsg = async (msgs) => {
if (!this.networkManager.hasActiveAdapters()) return; if (!this.networkManager.hasActiveAdapters()) return;
for (const msg of msgs) { for (const msg of msgs) {
if (this.bootTime > parseInt(msg.msgTime)) { if (this.bootTime > parseInt(msg.msgTime)) {
continue; continue;
} }
msg.id = MessageUnique.createUniqueMsgId( // this.context.logger.log(`[Satori] Debug: Processing message ${msg.msgId}`);
{ chatType: msg.chatType, peerUid: msg.peerUid, guildId: '' },
msg.msgId
);
await this.handleMessage(msg); await this.handleMessage(msg);
} }
}; };
@ -192,10 +190,6 @@ export class NapCatSatoriAdapter {
); );
const updatemsg = updatemsgs.find((e) => e.msgId === msg.msgId); const updatemsg = updatemsgs.find((e) => e.msgId === msg.msgId);
if (updatemsg?.sendStatus === SendStatusType.KSEND_STATUS_SUCCESS) { if (updatemsg?.sendStatus === SendStatusType.KSEND_STATUS_SUCCESS) {
updatemsg.id = MessageUnique.createUniqueMsgId(
{ chatType: updatemsg.chatType, peerUid: updatemsg.peerUid, guildId: '' },
updatemsg.msgId
);
await this.handleMessage(updatemsg); await this.handleMessage(updatemsg);
} }
} }
@ -298,7 +292,10 @@ export class NapCatSatoriAdapter {
try { try {
const event = await this.apis.EventApi.createMessageEvent(message); const event = await this.apis.EventApi.createMessageEvent(message);
if (event) { if (event) {
this.context.logger.logDebug(`[Satori] Emitting event ${event.type}`);
await this.networkManager.emitEvent(event); await this.networkManager.emitEvent(event);
} else {
this.context.logger.logDebug(`[Satori] Event creation returned null for msg ${message.msgId}`);
} }
} catch (error) { } catch (error) {
this.context.logger.logError('[Satori] 处理消息失败', error); this.context.logger.logError('[Satori] 处理消息失败', error);

View File

@ -120,6 +120,7 @@ export class SatoriWebSocketServerAdapter extends ISatoriNetworkAdapter<SatoriWe
return SatoriNetworkReloadType.Normal; return SatoriNetworkReloadType.Normal;
} }
async onEvent<T extends SatoriEmitEventContent> (event: T): Promise<void> { async onEvent<T extends SatoriEmitEventContent> (event: T): Promise<void> {
if (!this.isEnable) return; if (!this.isEnable) return;
@ -133,14 +134,25 @@ export class SatoriWebSocketServerAdapter extends ISatoriNetworkAdapter<SatoriWe
}; };
const message = JSON.stringify(signal); const message = JSON.stringify(signal);
let sentCount = 0;
this.logger.logDebug(`[Satori] onEvent triggered. Current clients: ${this.clients.size}`);
for (const [ws, clientInfo] of this.clients) { for (const [ws, clientInfo] of this.clients) {
if (clientInfo.identified && ws.readyState === WebSocket.OPEN) { const ip = (ws as any)._socket?.remoteAddress || 'unknown';
ws.send(message); if (ws.readyState === WebSocket.OPEN) {
clientInfo.sequence = this.eventSequence; if (clientInfo.identified) {
if (this.config.debug) { ws.send(message);
this.logger.logDebug(`[Satori] 发送事件: ${event.type}`); clientInfo.sequence = this.eventSequence;
sentCount++;
if (this.config.debug) {
this.logger.logDebug(`[Satori] 发送事件: ${event.type} to ${ip}`);
}
} else {
this.logger.logDebug(`[Satori] 客户端未认证,跳过发送. IP: ${ip}, Identified: ${clientInfo.identified}`);
} }
} else {
this.logger.logDebug(`[Satori] 客户端连接非 OPEN. State: ${ws.readyState}`);
} }
} }
} }
@ -171,36 +183,50 @@ export class SatoriWebSocketServerAdapter extends ISatoriNetworkAdapter<SatoriWe
private handleMessage (ws: WebSocket, data: string): void { private handleMessage (ws: WebSocket, data: string): void {
try { try {
const signal: SatoriSignal = JSON.parse(data); const signal = JSON.parse(data) as SatoriSignal | { op?: number; };
const clientInfo = this.clients.get(ws); const clientInfo = this.clients.get(ws);
if (!clientInfo) return; if (!clientInfo) return;
if (typeof signal?.op === 'undefined') {
this.logger.log(`[Satori] 收到无 OP 信令: ${data}`);
return;
}
if (signal.op !== SatoriOpcode.PING) {
this.logger.log(`[Satori] 收到信令 OP: ${signal.op}`);
}
switch (signal.op) { switch (signal.op) {
case SatoriOpcode.IDENTIFY: case SatoriOpcode.IDENTIFY:
this.handleIdentify(ws, clientInfo, signal.body as SatoriIdentifyBody); this.handleIdentify(ws, clientInfo, (signal as SatoriSignal).body as SatoriIdentifyBody);
break; break;
case SatoriOpcode.PING: case SatoriOpcode.PING:
this.sendPong(ws); this.sendPong(ws);
break; break;
default: default:
this.logger.logDebug(`[Satori] 收到未知信令: ${signal.op}`); this.logger.logDebug(`[Satori] 收到未知信令: ${JSON.stringify(signal)}`);
} }
} catch (error) { } catch (error) {
this.logger.logError(`[Satori] 消息解析失败: ${error}`); this.logger.logError(`[Satori] 消息解析失败: ${error}`);
} }
} }
private handleIdentify (ws: WebSocket, clientInfo: ClientInfo, body: SatoriIdentifyBody): void { private handleIdentify (ws: WebSocket, clientInfo: ClientInfo, body: SatoriIdentifyBody | undefined): void {
this.logger.logDebug(`[Satori] 处理客户端认证. Token required: ${!!this.config.token}, Body present: ${!!body}`);
// 验证 token // 验证 token
if (this.config.token && body.token !== this.config.token) { const clientToken = body?.token;
if (this.config.token && clientToken !== this.config.token) {
this.logger.log(`[Satori] 客户端认证失败: Token不匹配. Expected: ${this.config.token}, Received: ${clientToken}`);
ws.close(4001, 'Invalid token'); ws.close(4001, 'Invalid token');
return; return;
} }
clientInfo.identified = true; clientInfo.identified = true;
if (body.sequence) { if (body?.sequence) {
clientInfo.sequence = body.sequence; clientInfo.sequence = body.sequence;
} }
this.logger.log(`[Satori] 客户端认证通过. Sequence: ${clientInfo.sequence}`);
// 发送 READY 信令 // 发送 READY 信令
const readyBody: SatoriReadyBody = { const readyBody: SatoriReadyBody = {