Skip to content

feat: add browser MessagePort transport#1334

Draft
rvolosatovs wants to merge 1 commit into
mainfrom
feat/message-channel
Draft

feat: add browser MessagePort transport#1334
rvolosatovs wants to merge 1 commit into
mainfrom
feat/message-channel

Conversation

@rvolosatovs

Copy link
Copy Markdown
Member

Add the wrpc-message-channel crate, a wRPC transport over a browser MessagePort (one half of a MessageChannel, or a port transferred from a worker/window). A MessagePort is a single established bidirectional message stream, so it maps onto one wRPC connection that the framed transport multiplexes into an invocation's sub-streams.

connect bridges the event-based MessagePort API onto the AsyncRead/AsyncWrite byte-stream halves the framed transport expects. Since MessagePort is !Send while Invoke/Serve require Send, the port is moved into a spawn_local task and reached only through Send channels; the returned halves are Send and satisfy the bounds. Each direction is framed as discrete messages: a Uint8Array carries a chunk of bytes and a null message is the end-of-stream sentinel. Client is a one-shot Invoke and Server reuses the framed server.

The crate is gated to cfg(target_family = "wasm") (empty elsewhere) and wired into the wrpc facade behind a non-default message-channel feature, re-exported as transport::message_channel.

Assisted-by: claude:claude-opus-4-8

Add the `wrpc-message-channel` crate, a wRPC transport over a browser
`MessagePort` (one half of a `MessageChannel`, or a port transferred from
a worker/window). A `MessagePort` is a single established bidirectional
message stream, so it maps onto one wRPC connection that the framed
transport multiplexes into an invocation's sub-streams.

`connect` bridges the event-based `MessagePort` API onto the
`AsyncRead`/`AsyncWrite` byte-stream halves the framed transport expects.
Since `MessagePort` is `!Send` while `Invoke`/`Serve` require `Send`, the
port is moved into a `spawn_local` task and reached only through `Send`
channels; the returned halves are `Send` and satisfy the bounds. Each
direction is framed as discrete messages: a `Uint8Array` carries a chunk
of bytes and a `null` message is the end-of-stream sentinel. `Client` is
a one-shot `Invoke` and `Server` reuses the framed server.

The crate is gated to `cfg(target_family = "wasm")` (empty elsewhere) and
wired into the `wrpc` facade behind a non-default `message-channel`
feature, re-exported as `transport::message_channel`.

Assisted-by: claude:claude-opus-4-8
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