Expand description
WebSocket dev server.
whisker run opens a TCP listener, exposes a single
GET /whisker-dev route that upgrades to WebSocket, and pushes
patch messages to every connected client. The on-device
whisker-dev-runtime is the canonical client.
§Wire format
Two frame types:
Patches — binary frames laid out as:
[8 bytes: u64 BE — JSON header length]
[N bytes: JSON header { "kind": "patch", "table": {...} } ]
[rest: raw patch dylib bytes (no encoding) ]No base64. The dylib lands on the device with the original byte count, ~30 % smaller on the wire than the previous JSON-with- base64-string protocol.
Hello — text frame, {"kind":"hello","aslr_reference":<u64>}.
The device sends this on connect; the server stores the value
and the patcher uses it to compute the ASLR slide.
§Architecture
A single tokio::sync::broadcast channel: every connected socket
has its own subscriber receiver, so one PatchSender::send reaches
all clients. New connections see only payloads sent after they
subscribe — the receiver is at the tail end of the broadcast
buffer, not replayed.
Modules§
- wire_
jump_ table - Shared serde adapter used by
whisker-dev-runtime::hot_reloadtoo — both sides must agree on the JSON shape. Kept inline (not a shared crate) because the type is tiny and the duplication burden is one ~30-line module.
Structs§
- Patch
- Cheap-to-clone broadcast payload. The dylib bytes are held by
Arcso cloning into each subscribed client’s receive queue is just a refcount bump. - Patch
Sender - Cheap-to-clone handle for sending patches from the rest of the dev server (file watcher / builder / etc.) to every connected client.
Functions§
- serve
- Bind on
addr, spawn the axum server on the current tokio runtime, and return: