
























@@ -40,8 +40,10 @@ export type WhatsAppLiveConnection = {
4040heartbeat: TimerHandle | null;
4141watchdogTimer: TimerHandle | null;
4242lastInboundAt: number | null;
43+lastTransportActivityAt: number;
4344handledMessages: number;
4445unregisterUnhandled: (() => void) | null;
46+unregisterTransportActivity: (() => void) | null;
4547backgroundTasks: Set<Promise<unknown>>;
4648closePromise: Promise<WebListenerCloseReason>;
4749resolveClose: (reason: WebListenerCloseReason) => void;
@@ -51,6 +53,7 @@ export type WhatsAppConnectionSnapshot = {
5153connectionId: string;
5254startedAt: number;
5355lastInboundAt: number | null;
56+lastTransportActivityAt: number;
5457handledMessages: number;
5558reconnectAttempts: number;
5659uptimeMs: number;
@@ -83,6 +86,12 @@ function createNeverResolvePromise<T>(): Promise<T> {
8386return new Promise<T>(() => {});
8487}
858889+type SocketActivityEmitter = {
90+on?: (event: string, listener: (...args: unknown[]) => void) => void;
91+off?: (event: string, listener: (...args: unknown[]) => void) => void;
92+removeListener?: (event: string, listener: (...args: unknown[]) => void) => void;
93+};
94+8695function createLiveConnection(params: {
8796connectionId: string;
8897sock: WASocket;
@@ -108,8 +117,10 @@ function createLiveConnection(params: {
108117heartbeat: null,
109118watchdogTimer: null,
110119lastInboundAt: null,
120+lastTransportActivityAt: Date.now(),
111121handledMessages: 0,
112122unregisterUnhandled: null,
123+unregisterTransportActivity: null,
113124backgroundTasks: new Set<Promise<unknown>>(),
114125 closePromise,
115126resolveClose: resolveClosePromise,
@@ -232,6 +243,7 @@ export class WhatsAppConnectionController {
232243private readonly heartbeatSeconds: number;
233244private readonly keepAlive: boolean;
234245private readonly messageTimeoutMs: number;
246+private readonly appSilenceTimeoutMs: number;
235247private readonly watchdogCheckMs: number;
236248private readonly verbose: boolean;
237249private readonly abortSignal?: AbortSignal;
@@ -262,6 +274,7 @@ export class WhatsAppConnectionController {
262274this.keepAlive = params.keepAlive;
263275this.heartbeatSeconds = params.heartbeatSeconds;
264276this.messageTimeoutMs = params.messageTimeoutMs;
277+this.appSilenceTimeoutMs = Math.max(params.messageTimeoutMs, params.messageTimeoutMs * 4);
265278this.watchdogCheckMs = params.watchdogCheckMs;
266279this.reconnectPolicy = params.reconnectPolicy;
267280this.abortSignal = params.abortSignal;
@@ -311,6 +324,14 @@ export class WhatsAppConnectionController {
311324}
312325this.current.handledMessages += 1;
313326this.current.lastInboundAt = timestamp;
327+this.current.lastTransportActivityAt = timestamp;
328+}
329+330+noteTransportActivity(timestamp = Date.now()): void {
331+if (!this.current) {
332+return;
333+}
334+this.current.lastTransportActivityAt = timestamp;
314335}
315336316337getCurrentSnapshot(
@@ -323,6 +344,7 @@ export class WhatsAppConnectionController {
323344connectionId: connection.connectionId,
324345startedAt: connection.startedAt,
325346lastInboundAt: connection.lastInboundAt,
347+lastTransportActivityAt: connection.lastTransportActivityAt,
326348handledMessages: connection.handledMessages,
327349reconnectAttempts: this.reconnectAttempts,
328350uptimeMs: Date.now() - connection.startedAt,
@@ -369,6 +391,7 @@ export class WhatsAppConnectionController {
369391const listener = await params.createListener({ sock, connection });
370392connection.listener = listener;
371393this.current = connection;
394+connection.unregisterTransportActivity = this.attachTransportActivityListener(sock);
372395registerWhatsAppConnectionController(this.accountId, this);
373396this.startTimers(connection, {
374397onHeartbeat: params.onHeartbeat,
@@ -383,6 +406,7 @@ export class WhatsAppConnectionController {
383406if (connection?.unregisterUnhandled) {
384407connection.unregisterUnhandled();
385408}
409+connection?.unregisterTransportActivity?.();
386410throw err;
387411}
388412}
@@ -515,6 +539,7 @@ export class WhatsAppConnectionController {
515539this.socketRef.current = null;
516540}
517541connection.unregisterUnhandled?.();
542+connection.unregisterTransportActivity?.();
518543if (connection.heartbeat) {
519544clearInterval(connection.heartbeat);
520545}
@@ -563,9 +588,14 @@ export class WhatsAppConnectionController {
563588}, this.heartbeatSeconds * 1000);
564589565590connection.watchdogTimer = setInterval(() => {
566-const baselineAt = connection.lastInboundAt ?? connection.startedAt;
567-const staleForMs = Date.now() - baselineAt;
568-if (staleForMs <= this.messageTimeoutMs) {
591+const now = Date.now();
592+const transportStaleForMs = now - connection.lastTransportActivityAt;
593+const appBaselineAt = connection.lastInboundAt ?? connection.startedAt;
594+const appSilentForMs = now - appBaselineAt;
595+if (
596+transportStaleForMs <= this.messageTimeoutMs &&
597+appSilentForMs <= this.appSilenceTimeoutMs
598+) {
569599return;
570600}
571601const snapshot = this.getCurrentSnapshot(connection);
@@ -581,6 +611,24 @@ export class WhatsAppConnectionController {
581611}, this.watchdogCheckMs);
582612}
583613614+private attachTransportActivityListener(sock: WASocket): (() => void) | null {
615+const ws = sock.ws as SocketActivityEmitter | undefined;
616+if (!ws || typeof ws.on !== "function") {
617+return null;
618+}
619+620+const noteActivity = () => this.noteTransportActivity();
621+ws.on("frame", noteActivity);
622+623+return () => {
624+if (typeof ws.off === "function") {
625+ws.off("frame", noteActivity);
626+return;
627+}
628+ws.removeListener?.("frame", noteActivity);
629+};
630+}
631+584632private stopDisconnectRetries(): void {
585633if (!this.disconnectRetryController.signal.aborted) {
586634this.disconnectRetryController.abort();
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。