-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
25dc13e
commit 17fa94e
Showing
1 changed file
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
--- | ||
uip: "01XX" | ||
title: "%eyre/%iris: Support Websocket" | ||
description: "Support Websocket connections on Eyre/Iris" | ||
author: ~fidwed-sipwyn | ||
status: Draft | ||
type: Standards Track | ||
category: Kernel | ||
created: 2024-04-27 | ||
--- | ||
|
||
## Abstract | ||
|
||
This proposal adds Websocket functionally that works in a similar manner to existing `%eyre`/`%iris` HTTP features. 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 estabilished, 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). |