--- uip: "0125" title: "%eyre/%iris: Support Websocket" description: "Support Websocket connections on Eyre/Iris" author: ~fidwed-sipwyn status: Stagnant type: Standards Track category: Kernel created: 2024-04-27 --- ## Abstract This proposal adds Websocket functionality that works in a similar manner to the currently `%eyre`/`%iris` HTTP interface. Users who wish to receive Websocket connections will use the existing `%eyre`'s `%connect` `$task` to bind a URL path where the websocket handshakes will arrive (since they are technically also HTTP requests, this should be intuitive). To initiate a connection, users should pass a `%websocket-connect` `$task` to `%iris`. Once the connection is established, the client/server vanes interaction with the apps occurs through `%gall` pokes, facts and subscriptions. ## Motivation Websocket support will allow Urbit to interact with a wider variety of systems/protocols. ## Specification - **%eyre** will have a new `$gift` and a new `$task`: ```hoon :: $gift :: :: websocket-reponse: event to earth :: [%websocket-response event=websocket-event] :: $task :: :: receives websocket event from earth :: [%websocket-event event=websocket-event] ``` - And the following new types: ```hoon :: +websocket-connection: connection to be store in eyre state :: +$ websocket-connection $: app=term =inbound-request == :: +websocket-message: websocket message content :: +$ websocket-message $: opcode=@ud message=(unit data=octs) == :: +websocket-event: inbound/outbound websocket event :: +$ websocket-event $% [%accept ~] [%reject ~] [%disconnect ~] [%message message=websocket-message] == :: ``` - **%iris** will have two new `$gift`s and two new `$task`s: ```hoon :: $gift :: :: %websocket-handshake: outbound websocket-handshake to earth :: [%websocket-handshake id=@ud url=@t] :: %websocket-response: event to earth :: [%websocket-response id=@ud websocket-event:eyre] :: $task :: :: request to open websocket connection :: [%websocket-connect app=term url=@t] :: receives websocket event from earth :: [%websocket-event id=@ud event=websocket-event:eyre] ``` - And a new type: ```hoon :: +websocket-connection: websocket connection stored in iris state :: +$ websocket-connection $: app=term =duct id=@ud url=@t status=?(%pending %accepted) == ``` - %eyre will share the `$websocket-message` and `$websocket-event` types with %iris. - The only new `$task` that the app devs will utilize is the `%websocket-connect` from iris. - The existing `%cancel-request` `$task` from iris will be modified to also cancel websocket requests. - Server user flow: - The user exposes their app with the `%eyre`'s `%connect` `$task`. - When a handshake comes from earth, `%eyre` subscribes to the app's `/websocket-server/[eyre-id]` path and sends a `%websocket-handshake` poke with `[eyre-id inbound-request]`. The `eyre-id` will be used to represent that particular connection. - In response to `%websocket-handshake`, the user gives a fact with the `%accept` or `%reject` mark on `/websocket-server/[eyre-id]`. - After `%accept`ed the app can give `%message`s facts on `/websocket-server/[eyre-id]` and receives messages that comes as `%websocket-server-message`s pokes, containing `[eyre-id websocket-message]`. - If the subscription is kicked, then the connection is closed, or the user can give a fact with the `%disconnect` mark to close it. - Client user flow: - The user sends a request to initiate the connection by passing the `%websocket-connect` `$task` to `%iris` with `[app=term url=@t]`. - The user can cancel the request by using the `%cancel-request` `$task`. - If the connection succeeds `%iris` will subscribe to `/websocket-client/id`, with `id` representing that particular connection. - The app can give facts with the `%message` mark on `/websocket-client/id` and receives messages that comes as `%websocket-client-message`s pokes, containing `[id websocket-message]`. - If the subscription is kicked, then the connection is closed, or the user can give a fact with the `%disconnect` mark to close it. ## Rationale The approach followed here is a way to add the intended feature while reutilizing some of the existing logic and without adding a new vane. ## Backwards Compatibility Backwards compatibility is only affected if there are developers currently handling Websocket handshakes in the `%handle-http-request` poke. ## Reference Implementation Incoming ## Security Considerations Similar considerations as the currently HTTP implementation. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).