createWebSocketResponder
Answer requests the server sends: in code, for tools that only exist in the browser, or by a person, for approvals. The reverse of createWebSocketRequests.
Available from both react-websocket and react-websocket/core.
Usage
A request registered without a handler waits for a person. useAgentApproval registers one while mounted and renders what's waiting. The guide is AI agents.
Parameters
Handlers receive params typed as request returns them. If they're optional in your message type, handlers get params | undefined. Ids are typed number | string, so your Out type must accept both.
Returns
WebSocketResponder<P, R>:
onRequest
- With a handler, the request is answered in code. Return or resolve the result to reply with it. Throw or reject to send the
errorreply. - Without one, the request waits in
getSnapshot()until something callsrespondorrejecton it. - Several registrations for one method form a stack. The newest one takes new requests, and unregistering it hands them back to the one before. So a dialog and a badge can both hold
'approve', and hot reloading doesn't break it. - Unregistering never cancels requests that are already waiting or running. The function is safe to call more than once.
IncomingRequest
Only the first answer counts. signal aborts when:
Pass the signal on to fetch, a geolocation watch, or anything else the handler starts.
Errors
options.error receives one of these. Each is a DOMException, except what a handler throws:
Behavior
- One answer per request. While its connection lives, every request gets exactly one reply or error reply. A request the server sends again with an id that's still in flight is ignored.
- Tied to its connection. A request can only be answered on the connection it arrived on. When that connection closes, including through
reconnect(), the request is dropped and its signal aborts, and a late result is discarded. Replies are sent withvolatile, so they're never queued for the next connection, where the server wouldn't know the id. If your server keeps work across reconnects, have it send pending requests again when the client reconnects. - Doesn't connect. It answers whenever the client is open, but doesn't hold the connection, even while a request waits for a person.
useAgentApprovalholds it while mounted. - Requests are messages. Requests also reach
onMessage,lastMessageand state stores. The same goes for cancellations. - One per client. Two responders on one client both see every request, and one of them answers
NotFoundError. Also make surerequestdoesn't match the replies acreateWebSocketRequestsmanager on the same client waits for. With JSON-RPC, for example, a request has amethodand a reply doesn't. - Requires TypeScript 5.4+ for the inferred message types (it uses
NoInfer).