libp2p / universal-connectivity

Realtime decentralised chat with libp2p showing ubiquitous peer-to-peer connectivity between multiple programming languages (Go, Rust, TypeScript) and runtimes (Web, native binary) using QUIC, WebRTC and WebTransport
https://universal-connectivity.vercel.app
Other
87 stars 32 forks source link

Help js browser peers discover each other out of the box #95

Closed 2color closed 1 month ago

2color commented 1 year ago

Background

When I initially created this project, I aimed to have it simply work when loaded in the browser for demo purposes. I wanted to show how easy libp2p makes it for different runtimes and languages to connect to each other — even when behind NAT.

I wanted to be able to just share the URL as part of a talk/demo, and for browsers to just establish connectivity with each other.

Moreover, it expands the scope of this demo app to include a critical part of any libp2p app, namely peer discovery/routing.

Current challenges

Ideal case

Open questions

2color commented 1 year ago

Based on https://libp2p.io/implementations/, js-libp2p doesn't support Rendezvous in the browser

Screenshot 2023-09-27 at 12 27 04 PM
thomaseizinger commented 1 year ago

What does bootstrap refer to? And I am pretty sure rust-libp2p can do random walks :)

Seems to be outdated! I'll put it on my list for tomorrow to update!

2color commented 1 year ago

What does bootstrap refer to?

Not sure what you mean with this question

thomaseizinger commented 1 year ago

What does bootstrap refer to?

Not sure what you mean with this question

The first row in the screenshot you posted.

2color commented 1 year ago

I don't actually know what is referred to there. It links to the kad-DHT spec https://github.com/libp2p/specs/blob/master/kad-dht/README.md#bootstrap-process but it doesn't go into the actual details and it isn't clear what is referred to.

@p-shahi Any thoughts?

thomaseizinger commented 1 year ago

I don't actually know what is referred to there. It links to the kad-DHT spec libp2p/specs@master/kad-dht/README.md#bootstrap-process but it doesn't go into the actual details and it isn't clear what is referred to.

@p-shahi Any thoughts?

Yep, just realised that too. rust-libp2p definitely supports that so I'll update that!

maceip commented 1 year ago

To keep the magic alive I'd be interested in trying to come up with a way to get users (who can't or won't run local server clients) to collaborate in support of browser-browser connectivity. Harken back to the old folding@home or seti@home days?

I would personally donate a node with a public IP running relayV2, thus enabling users to drive-by connect using the js-peer in this demo -- but what's the fun in that and what are we showing them anyways?

Given how many conferences we all go to, I think a better use case would be to demo WebRTC data channel establishment & signaling via QRcode in person. This has an interesting property as it requires you to actually talk to people, and gives you a cool reason to do so. Each time you connect you get one non-financial/non-redeemable libp2p point to be proudly showcased in your git profile, via IPLD 💚

2color commented 1 year ago

Thanks for your input @maceip — I appreciate your willingness to help and donate.

Given how many conferences we all go to, I think a better use case would be to demo WebRTC data channel establishment & signaling via QRcode in person.

That's pretty neat, but it's worth pointing out that this approach would only work on a local network due to NAT hole punching. Here's some prior work on this:

maceip commented 1 year ago

precisely! what better way to demo the power of libp2p than at a conference hall with 10-10k people all on the same (v)LAN!

If you want an online demo that shows how a users browser window can connect to a hosted relay / hosted peer, we can definitely do that but if you are going to hardcode the multiaddr -- what is the user journey here?

Nevertheless, watching the the js helia / ipfs debug output (like in the repo's listed below ::hattip:: @achingbrain ) makes it worthwhile to just get something up that works:

https://github.com/ipfs-shipyard/www-helia-identify/tree/main/src https://github.com/ipfs-shipyard/www-libp2p-webtransport-sessions

I'm not sure the best way to donate here -- it's likely that i'll spin up some server, give it dns, and then in ~5 years i'll be on an island and forget about it and rm -rf it :(

thomaseizinger commented 1 year ago

Given how many conferences we all go to, I think a better use case would be to demo WebRTC data channel establishment & signaling via QRcode in person.

If both parties have a connection to the relay, all the QR code needs to contain is the nodes peer ID and you are good to connect!

maceip commented 1 year ago

I spun up a node on AWS in milan (closest region to istanbul), running latest helia / ubuntu / caddy. the username.rs domain was purchased by me a few days ago to try to take over the world but that never happened, so it is unused. I can donate this to y'all if needed. The AWS account has startup accelerator credits so at a minimum it will fund this relay for 12 months. at the moment it's not doing ci/cd, but can do later. ->

relay info:

https://relay.username.rs/info/

and the hosted js-peer, bootstrapping off the relay:

https://relay.username.rs/u/

and the stable multiaddr browsers can use as a bootstrap:

/dns4/relay.username.rs/tcp/443/wss/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3

will upload the repo and share -- y'all can decide what you want to do with it or how to manage it.

polus-arcticus commented 1 year ago

Thanks for opening this @2color this type of functionality was provided out of the box with js-libp2p-webrtc-star where i could simply https://github.com/libp2p/js-libp2p-webrtc-star/blob/master/packages/webrtc-star-signalling-server/DEPLOYMENT.md and have two browser windows doing pubsub and automatically discovering each other, for ui/ux that feels just like doing pubsub over a centralized server. But recreating this after the depreciation of the star protocols has proven a major challenge for me

thomaseizinger commented 1 year ago

Wrote up a proposal for ambient peer discovery here: https://github.com/libp2p/specs/discussions/587

2color commented 1 year ago

Thanks @maceip for your efforts. I was able to connect from the browser app to /dns4/relay.username.rs/tcp/443/wss/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3 get the browser node's listen address then connect to another browser tab.

Not exactly sure why, but even once the connection between two browser nodes is established, exchanging chat messages doesn't work. Not sure exactly why.

If you want an online demo that shows how a users browser window can connect to a hosted relay / hosted peer, we can definitely do that but if you are going to hardcode the multiaddr -- what is the user journey here?

We were thinking of prefilling the multiaddr input field with the deployed rust peer multiaddr, and allowing the user to optionally connect to it or alternatively, passing in your own relay multiaddr.

At this point, messages in the chat should get relayed between browser nodes, since the rust peer is also subscribed to the pubsub topic.

There may be some limits to how many concurrent browser peers can exchange messages by only being connected to the rust peer. This is where directly connecting to other browser peers may be useful and where ambient peer discovery may be useful.

@thomaseizinger How does that align with your vision and understanding of the protocol constraints?

maceip commented 1 year ago

Thanks @maceip for your efforts. I was able to connect from the browser app to /dns4/relay.username.rs/tcp/443/wss/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3 get the browser node's listen address then connect to another browser tab.

Not exactly sure why, but even once the connection between two browser nodes is established, exchanging chat messages doesn't work. Not sure exactly why.

Just tested it by: On one tab I went to /u/, it connected to bootstrap relay, then I copied it's WebRTC multiaddr:

ip4/127.0.0.1/tcp/8001/ws/p2p/12D3KooWDoap6J1qAP17dvR8KgaknSZSFSamxFeggEc5Qzecqto3/p2p-circuit/webrtc/p2p/12D3KooWGW3nqSaQAfqWvwCotAySUyJRtXktMXRcTMB7frkU6krR

I then opened another tab and browsed to /u/, and after it connected to the relay I pasted in the above WebRTC multiaddr and hit connect. It connected and then chat worked:

Screenshot_20231004-084825 Screenshot_20231004-084729

2color commented 1 year ago

Thanks @maceip — I tried again and it works.

It didn't work the first time because I mistakenly used the /p2p-circuit/p2p/ relay address rather than the webrtc one. It results in a connection, but I presume all traffic is relayed as it is a circuit relay v2 connection rather than a direct WebRTC one that is constrained and therefore doesn't work for gossipsub messages:

Screenshot 2023-10-04 at 5 03 17 PM

Anyway, with the webrtc multiaddr, the chat works too! Now we have to figure out ambient peer discovery

thomaseizinger commented 1 year ago

There may be some limits to how many concurrent browser peers can exchange messages by only being connected to the rust peer. This is where directly connecting to other browser peers may be useful and where ambient peer discovery may be useful.

@thomaseizinger How does that align with your vision and understanding of the protocol constraints?

There are for sure limits! We don't have any numbers on gossipsub messages but the IPFS bootstrap nodes handled 40k connections pretty easily with ~ 300kb RAM per connection. Based on the available RAM on the smallest fly.io instance that we are running on, that is about 500 connections :)

thomaseizinger commented 1 year ago

There may be some limits to how many concurrent browser peers can exchange messages by only being connected to the rust peer. This is where directly connecting to other browser peers may be useful and where ambient peer discovery may be useful. @thomaseizinger How does that align with your vision and understanding of the protocol constraints?

There are for sure limits! We don't have any numbers on gossipsub messages but the IPFS bootstrap nodes handled 40k connections pretty easily with ~ 300kb RAM per connection. Based on the available RAM on the smallest fly.io instance that we are running on, that is about 500 connections :)

This made me think that we probably want to add some connection limits :)

https://github.com/libp2p/universal-connectivity/pull/102

2color commented 7 months ago

A couple of thoughts on how we could we could improve browser-to-browser connectivity out of the box this without necessarily introducing a new protocol: