Skip to content

Share one process-wide WebSocket listener across native product executions #355

Description

@pgherveou

Description

The native bridge currently starts an independent localhost WebSocket listener for every NativeProductExecution. App, Widget, and Chat executions therefore each receive a separate port and authentication token.

This design provides good isolation and has relatively low overhead because all listeners already share one process-wide Tokio executor. However, it creates unnecessary listeners, accept loops, ports, and per-listener connection limits.

Introduce one WebSocket listener owned by NativeTrUApiHostRuntime, while retaining a separate authenticated WebSocket connection for each product execution.

Proposed design

  • Start one loopback listener for the lifetime of the shared native host runtime.
  • Register each NativeProductExecution with a unique cryptographically secure token.
  • Resolve the token during the WebSocket handshake to the corresponding trusted product context.
  • Create a separate ProductRuntime and connection state for every accepted product connection.
  • Revoke an execution token and close its connections when that execution closes.
  • Keep queues, subscriptions, callbacks, event buses, and backpressure isolated per execution.
  • Stop the listener only when the shared host runtime shuts down.

This shares server infrastructure without multiplexing App and Chat traffic over one WebSocket connection.

Non-goals

  • Sharing one WebSocket connection between multiple products.
  • Allowing clients to select or provide their own product identity.
  • Sharing request IDs, subscriptions, outbound queues, or backpressure state between executions.
  • Addressing renderer decoding or queue-bounding concerns reported separately.

Acceptance criteria

  • App, Widget, and Chat executions connect through the same localhost port.
  • Every execution receives an independent authentication token.
  • A token can access only its registered product context.
  • Closing one execution revokes its token and terminates only its connections.
  • Restarting or failing one product does not affect other products.
  • Connection and queue limits are enforced both globally and per execution.
  • The listener continues serving remaining products after one execution closes.
  • Tests cover token isolation, revocation, reconnection, concurrent products, and host shutdown.
  • The legacy NativeTrUApiCore API continues to work without behavioral changes.

Security considerations

The server must derive product identity exclusively from the registered token, not from client-supplied product identifiers. Revoked tokens must be rejected immediately, and token matching must retain the existing timing-safe authentication properties.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions