WebSockets on the IC (PsychedelicDAO)

WebSockets on the IC

Seeing as the Internet Computer is the only blockchain to natively serve assets over http (as well as soon make outbound http calls to external services), we (PsychedelicDAO) think that the next natural continuation is to find a way to implement the WebSocket API. Not only would it provide tremendous value for services built on the IC, but it would add to the growing value prop that the IC has over other chains.

We want to be explicit that this post is not meant to act as a proposal for a technical implementation of the WebSocket API, but rather an attempt to lay out an initial vision for the community to run with.

Why WebSockets on the IC?

Currently, if a client wants to poll for data, it can create a loop that continuously requests data from an IC canister. This is exactly what we do in order to provide a somewhat live price feed for swaps on Sonic.

With websockets, clients wouldn’t have to drive an unnecessary amount of requests to the IC. Instead, you’d be able to have services that can automatically, and on-chain if I might add, stream data between client and service.

Let’s take DSCVR, the popular social platform on the IC, and Plug, our wallet solution, as two examples to showcase the benefits of on-chain websockets.

DSCVR w/ websockets

DSCVR could become an extremely quick and snappy application with websockets - all likes, comments, and any other interaction could be loaded live. Additionally, on-chain audio streams could become a thing. Goodbye Twitter Spaces for all of web3.

Plug w/ websockets

Notifications. Plug could automatically plug in (:wink:) to the dApps that you’ve connected to and accept and display live push notifications via websockets.

High Level Implementation Details

Much like http calls, WebSockets on the IC would need to have protocols put in place for both inbound and outbound requests. Let’s dive into the difference between the two.

Inbound Websocket (Client Initiated)

Inbound websocket refers to a client that wants to initiate a websocket with a canister. A great example of this could be actual real time price fetching for tokens from Sonic.

In this scenario we would have the user initiate a request to open a websocket, at which time the boundary nodes would be responsible for calling ws_open on the specified canister to open the websocket.

Once open, the boundary node can call ws_data to write data from the client, and the canister can call ws_data at the subnets management API to write to the client.

A close can be initiated by either the client to the boundary node, that would call ws_close on the canister. The canister can call the management API’s ws_close to terminate the connection as well.

Outbound Websocket (Canister Initiated)

Outbound websocket refers to a canister opening up a websocket with an external websocket server (if we have inbound websockets at this time, could be another canister).

To open a new websocket, the canister calls ws_open on the subnets management API, which passes the call along to the boundary node to initiate on external service.

Canister calls ws_data on the management API to write to the websocket and the boundary node can call ws_data on the canister to read from the websocket.

Close is initiated by the canister to the management API’s ws_close or by the boundary node to the canister’s ws_close method.

Unknowns

Subnet consensus is where things get tricky – we don’t have a proposed solution here, but would love help from the community (we have heard OpenChat has worked on some WebRTC implementations) and the foundation to keep this conversation going forward.

We Need Your Help

We understand that this feature might be ambitious for the network and that there are currently a lot of other exciting and time consuming initiatives on the Internet Computer’s roadmap.

However, we have heard websockets on the IC brought up countless times in conversations with other builders in the community. We would like to start pushing the conversation forward now, so that when the time / resources are available, we have already ironed out some details.


Excited about websockets on the IC? Come join us for Psychedelic TownHall 03, August 11th (day of posting) at 1pm EST. We’ll be discussing this proposal and opening up the floor for thoughtful contributions from the community.

:alien:

39 Likes

Absolutely. This kind of foresight, which improves the user experience when running on-chain dapps, is exactly what the IC requires. For broad acceptance to occur, the IC must provide a user experience that is comparable to or better than that of web 2 applications.

I’m hoping that the community will band together on this and begin working on some of the details.

5 Likes

I agree that WebSocket support would be amazing. Over a year ago we had some preliminary discussions about this. Especially now that http requests are about to come out, it might be an ideal time to revive the conversation armed with our new knowledge and experience.

15 Likes

Thank you for posting details on the forum. I am excited to see more of PsychedelicDAOs suggestions. Seems awesome.

I think you’ll be surprised by how much the developer community and ICPMN members pay attention and sincerely value your input.

3 Likes

Web sockets would open up many uses cases for mobile world. Who ever heard of an app that doesn’t do push notifications.

1 Like

Interesting idea @Sherlocked! From the tweets i had the impression that you guys would share a design of how it could work, but from this post it seems like it’s more of a feature request. Do i understand correctly that there isn’t a plan for the “how” yet and you hope to work that out here?

4 Likes

Thank you for this post @Sherlocked . I am very happy to see such discussions in the community.
One thing I am not clear of after reading this post, is the transition from a WebSocket stream to canister messages (the ws_data function in your diagrams):

  • Would the canister be responsible to buffer and frame messages? Or would the boundary node do that?
  • If it should happen in the BN, it needs to have some framing logic. Would that be per canister?
  • If not, the canister should be able to buffer possibly large amounts of data, deal with data that is broken into several messages, etc.
  • If the canister is responsible for all that, can we just send the data as ingress messages?
  • There are other considerations such as how much buffering we want in the BN even if it does not do framing, ordering of data chunks, etc.

Looking forward to having your thoughts on these aspects!

Yotam

2 Likes

Who is the expert at the Foundation on web sockets? This will need protocol level support and is a perfect example of where App developers need something, but cannot do it themselves as it is at the most fundamental level.

Subnet consensus - something should be implemented for usage, with a tag ‘beta’ or ‘Subnet consensus not provided’, as having this sooner than rather later would be ideal.

2 Likes

Likely inbound queries could be added via websockes much more easily than the other three quadrants of the inbound/outbound - query/update matrix.

Maybe we could explore there?

Great question!

@yotam (Yotam Harchol, Researcher) who replied above and @raymondk (Raymond Khalife, Senior Engineering Manager) are the folks we pinged for this thread because we think their work is closest to this.

1 Like

Thanks @diegop . @Sherlocked & @yotam @raymondk Summary of what I read about. this so far.

Realtime - would not be the goal. Users would still expect a delay of 2 seconds for query calls but they would be served over open web sockets rather than re-opening http requests. I expect that many developers who want web sockets do not realize this; game devs & other real time apps. — There would still be delay for consensus — “We have spoken with a bunch of people and they want it”, but in the context of real-time web apps right?

The benefit - would be a ‘light weight’ open web-socket that allows developers to get data as it reaches consensus without ‘polling’ every x —arbitrary— seconds.

Boundary nodes - seem like the correct place to manage these connections as icx-proxy already handles https requests.

The implementation should seek to keep ‘tamper-proofness’ and decentralization.

5 Likes

I am trying to better understand the use cases. Would you say a “push notification” service (canister->browser) that uses websockets underneath is enough? Or would you want to have a fully operational two-way websocket?

3 Likes

Me too, I do not see any benefit for the end user here, only to the developer (As real time is not a goal), or am I missing someting?

I also like the idea of two-way websockets, I think graphql subscription is a great example. Even if it isn’t real-time, it’s live. For example the Plex (movie organizer) shows new movies and changes without reload, which is very convenient.

Definitely not a MUST, but websocket on blockchain? Really cool :slight_smile:

Hi @janosroden
Thanks for the additional use-cases. They are both other examples of server pushing data to the client. Since you mention that two-way websockets would be nice, do you know of any use-cases for the other direction: client to server?

I meant the graphql subscription as an example of two way communication ((un)subscribe on websocket and get data on the same channel).
Of course the client can send subscribe requests to the server via a regular request and get updates on websocket. But in this case you’ll need to take extra steps (adjust a library for e.g.) because it’s simply unusual.

Got it, thanks for your explanations! So you setup a websocket and then manage multiple subscriptions through it. Indeed one could achieve the same using update calls, but that would require modifications on the client side.

1 Like

Hey everyone,

I would like to provide a quick update of what has been going on with regards to enabling WebSockets on the Internet Computer.

This post started a WebSockets-collaboration between PsychedelicDAO and DFINITY. Together, we aim to come up with a proof of concept following the design outlined in this thread. Our goal is to build a proof of concept that requires minimal changes to the IC core such that we can better understand the requirements and challenges involved, and iterate quickly.

Our current design follows closely the one in the original post above:

  • WS Gateway: we use a gateway as an intermediary between the client and the backend hosted on the IC. The gateway provides a WebSocket endpoint to the client and interfaces with the IC.
  • WS Library: we build a library for the client and the backend that takes care of all the connection management (e.g, keeping track of all open connections), interfacing with the gateway, and providing certification.

For more details take a look at the following doc.

We are curious to hear your thoughts and will keep you updated as we make progress!

8 Likes

Amazing. I love to see collaborations between the community and Dfinity. Building trust and building infra. Well done guys

2 Likes