Skip to content

[Feature]: Replace WebSocket signaling with HTTP signaling #377

Description

@imxade

Problem Statement

Rein currently keeps a WebSocket connection open at /ws to exchange WebRTC offers, answers, ICE candidates, authentication errors, and to control peer-session cleanup. Input and video already travel over WebRTC, so the persistent WebSocket is used only for signaling and lifecycle management.

Remove WebSocket signaling completely to simplify the transport model and avoid maintaining an additional persistent connection alongside WebRTC.

Proposed Solution

Replace /ws with authenticated HTTP signaling while preserving one RTCPeerConnection per viewer.

A possible design is non-trickle ICE with short-lived endpoints:

  • POST /api/webrtc/sessions creates a session and returns a complete SDP offer after server ICE gathering finishes.
  • The client sets the offer, creates an answer, waits for browser ICE gathering to finish, and submits the complete SDP answer.
  • POST /api/webrtc/sessions/:id/answer applies the answer.
  • DELETE /api/webrtc/sessions/:id explicitly releases an abandoned or closed session.
  • Server-side negotiation timeouts and ICE connection-state cleanup replace WebSocket-close cleanup.

The final endpoint shape may differ, but WebSocket and trickle signaling should be removed entirely.

The implementation must retain:

  • WebRTC H.264 video delivery.
  • input-unordered for movement, scrolling, zoom, and touch.
  • input-ordered for clicks, keyboard, text, and clipboard actions.
  • Timing-safe token authentication for remote callers.
  • Runtime configuration updates for active InputHandler instances.
  • Useful error reporting through HTTP responses and /debug logging.

Alternatives Considered (Optional)

  • Keep the existing WebSocket signaling connection.
  • Use HTTP plus SSE for trickle ICE; this still adds a persistent signaling stream and is not preferred.
  • Use long polling for trickle candidates.

Non-trickle ICE is attractive for LAN use because candidates can be included in the SDP payload and exchanged with a small number of HTTP requests.

Additional Context (Optional)

Suggested acceptance criteria:

  • No application code opens or handles /ws.
  • Direct ws and @types/ws dependencies are removed if no longer required directly.
  • A remote LAN client can negotiate video and both DataChannels through authenticated HTTP endpoints.
  • Multiple simultaneous clients and reconnects work correctly.
  • Unanswered offers and disconnected clients are cleaned up without relying on a WebSocket close event.
  • Signaling payloads have size limits, validation, and appropriate HTTP error responses.
  • Existing debug-log SSE may remain because it is unrelated to WebRTC signaling.
  • README architecture and firewall documentation describe the new signaling flow.
  • Tests cover successful negotiation, invalid sessions, authorization failures, and cleanup.

Related: #376 explores sharing a single UDP port across multiple WebRTC clients; that work is independent of signaling transport.

Checklist

  • I have searched for existing feature requests to avoid duplicates

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions