Skip to content

webui: actually close the signaling WebSocket - #53

Merged
Rust-KVM merged 1 commit into
devfrom
claude/webui-reconnect-leak-fix
Oct 11, 2026
Merged

Rust-KVM merged 1 commit into
devfrom
claude/webui-reconnect-leak-fix

Conversation

@Rust-KVM

@Rust-KVM Rust-KVM commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Requested by 4c · project thread

Summary

Before: #46 did not stop the leak. After a session was taken over, dropped or failed to connect, the signaling WebSocket stayed open, so each Reconnect still added one more established connection on the device.

After: the signaling socket is closed when a session ends (taken over or lost) and on every failed connection attempt (send-offer error, ICE failure, data-channel timeout).

How

gloo-net's Sink::close is a no-op and its WebSocket has no Drop, so #46's sink.close() did nothing. connect() now creates the raw web_sys::WebSocket, wraps it with WebSocket::try_from for the existing stream/sink code, and keeps the raw handle in Peer::signaling_ws. Peer::close() and each error path call close() on that handle. Adds the WebSocket web-sys feature.

Testing

  • cargo +nightly fmt --all (CI)
  • cargo +nightly clippy --workspace --release --all-targets -- -D warnings (CI)
  • cargo +nightly test --workspace (CI)
  • Frontend touched: trunk build --locked and wasm32 clippy in crates/rkvm-web (CI)
  • Tested on an RK3588 device: two browser tabs took the session from each other and clicked Reconnect repeatedly. Every old signaling WebSocket received a close and only one was open at any time; ESTABLISHED connections on the device's port 80 stayed at 3 after 6 and after 12 takeovers (previously grew from 2 to 10). The app's total fd count still grows by about 3.5 per session; those are non-TCP (UDP sockets / dmabuf) and are tracked separately, not caused by this change.

Checklist

  • No #[allow(...)] suppressions and no new unwrap() / expect() in production paths
  • Hot paths stay zero-copy; periodic loops use MissedTickBehavior::Delay
  • Shared protocol types live in rkvm-proto
  • RPC method set changed → not applicable
  • Module tree or build invariants changed → not applicable

🤖 Generated with Claude Code

https://claude.ai/code/session_01PbdzY6PfT28goR4BhqdsXR

#46 closed the gloo sink to end the signaling socket, but gloo-net's
Sink::poll_close is a no-op and its WebSocket has no Drop, so the
socket stayed open: after three takeovers each page still held four
signaling sockets and the device's established :80 connections went
from 2 to 10.

Open the socket as a web_sys::WebSocket, keep a handle in Peer and call
close() on it in Peer::close (session lost or taken over) and on every
connect failure path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Rust-KVM Rust-KVM self-assigned this Oct 11, 2026
@github-actions github-actions Bot added the rkvm-web Leptos / WASM frontend label Oct 11, 2026
@Rust-KVM
Rust-KVM merged commit db4f1e8 into dev Oct 11, 2026
13 checks passed
@Rust-KVM
Rust-KVM deleted the claude/webui-reconnect-leak-fix branch October 12, 2026 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rkvm-web Leptos / WASM frontend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants