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
onBroadcastHelperProgerssUpdate (..._args: unknown[]): any {
}
onNtMsgSyncContactUnread (..._args: unknown[]): any {
}
}

View File

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

View File

@ -120,6 +120,7 @@ export class SatoriWebSocketServerAdapter extends ISatoriNetworkAdapter<SatoriWe
return SatoriNetworkReloadType.Normal;
}
async onEvent<T extends SatoriEmitEventContent> (event: T): Promise<void> {
if (!this.isEnable) return;
@ -133,14 +134,25 @@ export class SatoriWebSocketServerAdapter extends ISatoriNetworkAdapter<SatoriWe
};
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) {
if (clientInfo.identified && ws.readyState === WebSocket.OPEN) {
ws.send(message);
clientInfo.sequence = this.eventSequence;
if (this.config.debug) {
this.logger.logDebug(`[Satori] 发送事件: ${event.type}`);
const ip = (ws as any)._socket?.remoteAddress || 'unknown';
if (ws.readyState === WebSocket.OPEN) {
if (clientInfo.identified) {
ws.send(message);
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 {
try {
const signal: SatoriSignal = JSON.parse(data);
const signal = JSON.parse(data) as SatoriSignal | { op?: number; };
const clientInfo = this.clients.get(ws);
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) {
case SatoriOpcode.IDENTIFY:
this.handleIdentify(ws, clientInfo, signal.body as SatoriIdentifyBody);
this.handleIdentify(ws, clientInfo, (signal as SatoriSignal).body as SatoriIdentifyBody);
break;
case SatoriOpcode.PING:
this.sendPong(ws);
break;
default:
this.logger.logDebug(`[Satori] 收到未知信令: ${signal.op}`);
this.logger.logDebug(`[Satori] 收到未知信令: ${JSON.stringify(signal)}`);
}
} catch (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
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');
return;
}
clientInfo.identified = true;
if (body.sequence) {
if (body?.sequence) {
clientInfo.sequence = body.sequence;
}
this.logger.log(`[Satori] 客户端认证通过. Sequence: ${clientInfo.sequence}`);
// 发送 READY 信令
const readyBody: SatoriReadyBody = {