From 3108ffe3e7d721e7775a8849fe4683969bb72683 Mon Sep 17 00:00:00 2001 From: wonder_land <61005155+kunwl123456@users.noreply.github.com> Date: Thu, 19 Feb 2026 15:40:04 +0800 Subject: [PATCH] fix(channel): update last_recv on WS Ping/Pong frames in Lark channel Feishu WebSocket server sends native WS Ping frames as keep-alive probes. ZeroClaw correctly replied with Pong but did not update last_recv, so the heartbeat watchdog (WS_HEARTBEAT_TIMEOUT = 300s) triggered a forced reconnect every 5 minutes even when the connection was healthy. Two fixes: - WsMsg::Ping: update last_recv before sending Pong - WsMsg::Pong: handle explicitly and update last_recv (was silently swallowed by the wildcard arm) Co-Authored-By: Claude Sonnet 4.6 --- src/channels/lark.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/channels/lark.rs b/src/channels/lark.rs index e071a0c..196b7c9 100644 --- a/src/channels/lark.rs +++ b/src/channels/lark.rs @@ -322,7 +322,8 @@ impl LarkChannel { msg = read.next() => { let raw = match msg { Some(Ok(WsMsg::Binary(b))) => { last_recv = Instant::now(); b } - Some(Ok(WsMsg::Ping(d))) => { let _ = write.send(WsMsg::Pong(d)).await; continue; } + Some(Ok(WsMsg::Ping(d))) => { last_recv = Instant::now(); let _ = write.send(WsMsg::Pong(d)).await; continue; } + Some(Ok(WsMsg::Pong(_))) => { last_recv = Instant::now(); continue; } Some(Ok(WsMsg::Close(_))) | None => { tracing::info!("Lark: WS closed — reconnecting"); break; } Some(Err(e)) => { tracing::error!("Lark: WS read error: {e}"); break; } _ => continue,