Skip to content

Fix: TCP connections never send a keepalive, causing periodic disconnects - #416

Open
Fimeg wants to merge 1 commit into
QuantumEntangledAndy:masterfrom
Fimeg:fix/tcp-keepalive
Open

Fix: TCP connections never send a keepalive, causing periodic disconnects#416
Fimeg wants to merge 1 commit into
QuantumEntangledAndy:masterfrom
Fimeg:fix/tcp-keepalive

Conversation

@Fimeg

@Fimeg Fimeg commented Jul 2, 2026

Copy link
Copy Markdown

Problem

Cameras connected over TCP (the common case — address = "ip:9000", as opposed to uid = "..." over UDP) silently drop their Baichuan session after a few minutes of otherwise-idle traffic, then reconnect. The reconnect is automatic, but it surfaces as a periodic blip in downstream consumers (Frigate, etc.), which is disruptive for continuous recording and motion detection.

Root cause

UDP sessions are kept alive by the camera itself: it sends MSG_ID_UDP_KEEP_ALIVE, which neolink acknowledges in BcCamera::keepalive(). TCP has no equivalent — nothing flows during idle periods — so the camera times the session out. There is a BcCamera::ping() (MSG_ID_PING) that looks purpose-built for this, but it is currently dead code (no call sites).

Fix

Send a fire-and-forget MSG_ID_PING every 60s on TCP connections only, to hold the session open. UDP is left untouched, since it already keeps itself alive.

  • BcCamera::new() now tracks whether the transport is UDP and, for TCP, spawns a task that sends MSG_ID_PING on an interval. The task ends on its own once the connection goes away (the send returns an error).
  • BcConnection::send is widened from pub(super) to pub(crate) so the keepalive can be sent without subscribing for a reply.

Validation

The same approach (a periodic MSG_ID_PING on TCP) has been running in production on TCP/Baichuan cameras (port 9000) where it eliminated reconnects that previously recurred every few minutes without fail. This PR ports that fix to current master.

TCP-connected cameras drop their Baichuan session after a few minutes
of otherwise-idle traffic, forcing a reconnect that surfaces as a
periodic blip in downstream consumers (Frigate, etc.). UDP sessions are
kept alive by the camera itself, which sends MSG_ID_UDP_KEEP_ALIVE and
which we acknowledge; TCP had no equivalent, so nothing kept the
session warm. Send a periodic MSG_ID_PING on TCP connections to hold
the session open. The ping is fire-and-forget and any reply is ignored.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant