Ephemeral WebSocket RequestRelay sessions were getting an immediate empty binary frame after HTTP 101, which desktop clients parse as RendezvousMessage{union:None} and disconnect before RelayResponse.
Treat RustDesk empty WebSocket keepalive replies as peer heartbeat activity. Without this, reverse-proxied WSS clients could stay connected at the WebSocket layer but still be cleaned from the in-memory peer map after RegTimeout, causing the server to close the active rendezvous session.
Add a regression assertion that RustDesk's empty keepalive echo refreshes the peer heartbeat timestamp.
Refs #144
Reported-by: kido <70244282+odixz@users.noreply.github.com>
Tested-by: kido <70244282+odixz@users.noreply.github.com>
Send empty binary keepalive frames on signal WebSockets and ignore empty RustDesk heartbeat replies across the WS protobuf adapter. This prevents reverse-proxied WSS clients from timing out after the advertised keep_alive interval.
Document the Nginx /ws/id and /ws/relay upstream mapping for BetterDesk Docker deployments.
Fixes#144
Reported-by: @odixz
Add a new betterdesk-server Go codebase (server, api, auth, db, relay, signal, metrics, audit, ratelimit, proto, tools, tests) and related deployment/migration scripts. Add a comprehensive SECURITY_AUDIT_2026-03-01 report and .gitattributes; update copilot-instructions (ALL-IN-ONE v2.4.0), README, VERSION, Dockerfiles, scripts, docker-compose and entrypoint. Large updates to web-nodejs (translations, routes, services, frontend assets and middleware) and numerous new utilities; remove legacy Flask web files and archive hbbs-patch-v2 artifacts. Prepares repository for PostgreSQL support, DB migration tooling and the new Go server as the production backend.