Skip to content

Commit

Permalink
websocket: initial draft
Browse files Browse the repository at this point in the history
  • Loading branch information
marcusmiguel committed Apr 27, 2024
1 parent 25dc13e commit 17fa94e
Showing 1 changed file with 123 additions and 0 deletions.
123 changes: 123 additions & 0 deletions UIPS/UIP-01XX.md
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).

0 comments on commit 17fa94e

Please sign in to comment.