Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an example of rust-libp2p running in the browser #23

Closed
tomaka opened this issue Nov 1, 2017 · 22 comments
Closed

Add an example of rust-libp2p running in the browser #23

tomaka opened this issue Nov 1, 2017 · 22 comments
Labels
difficulty:easy getting-started Issues that can be tackled if you don't know the internals of libp2p very well help wanted priority:nicetohave

Comments

@tomaka
Copy link
Member

tomaka commented Nov 1, 2017

With asmjs and/or wasm.

Is that an objective as well? It should be easy to achieve.

@rphmeier
Copy link
Contributor

rphmeier commented Nov 7, 2017

This is somewhat an objective. You're more experienced with the WASM side of things than I am, but I'd imagine all our generic future-based stuff would work, while tokio/mio/specific transports would not. We would need JS glue for hooking into the event loop, WS, WebRTC transports from there, along with Rust libraries meant to interface with that JS glue.

Datastore could be useful as well.

Plugging that into the light client code would be pretty straightforward then, and we could have a light client running in the chrome extension from that point.

@daviddias
Copy link
Member

You can run libp2p in the browser today by using the JavaScript implementation https://github.com/libp2p/js-libp2p

You can find an example here https://github.com/libp2p/js-libp2p/tree/master/examples/libp2p-in-the-browser

@tomaka
Copy link
Member Author

tomaka commented Jan 16, 2018

It is now possible to open a websocket listener from the browser by compiling for emscripten.
The gist here shows how to drive a future to completion using the stdweb crate.

Things still to be done:

  • Get crypto to work. The ring library doesn't compile for emscripten.
  • Add continuous integration. Unfortunately travis is not the most appropriate solution to compile for emscripten, and even if we manage to compile the listener testing it would require a javascript interpreter.

@tomaka
Copy link
Member Author

tomaka commented Mar 22, 2018

Add continuous integration. Unfortunately travis is not the most appropriate solution to compile for emscripten, and even if we manage to compile the listener testing it would require a javascript interpreter.

This is done.

Get crypto to work. The ring library doesn't compile for emscripten.

This is not going to happen anytime soon.
I think the best solution is to tweak the paritytech/ring repo to use the WebCrypto API when compiling for emscripten.

@gnunicorn
Copy link
Contributor

gnunicorn commented Jul 18, 2018

Futures supports stdweb (since version 0.2), which in turn supports wasm32-unknown-unknown-targets now, too. So, if we can upgrade futures to 0.2

Regarding

I think the best solution is to tweak the paritytech/ring repo to use the WebCrypto API when compiling for emscripten.

I very much agree with brian smith, that getting WebCrypto into Ring will be a challenge, already because ring is synchronous, while WebCrypto returns promises.

I think the better approach would be to refactor libp2p to use WebCrypto and std_web for wasm-targets, dropping ring altogether in that case. However, that means making a bunch of things async than they are right now.


Edit: that might also turn out to be non-trivial, as WebCrypto doesn't yet support all algorithms, that we need e.g. secp256k1. So I guess for some curves we might be more vulnerable within the wasm-environment 🤔 .

@tomaka
Copy link
Member Author

tomaka commented Jul 18, 2018

So, if we can upgrade futures to 0.2

Nothing in the Rust ecosystem supports futures 0.2, so that's no-no. However it's possible to use futures 0.1 as well. We just need some manual glueing.

@tomaka
Copy link
Member Author

tomaka commented Jul 18, 2018

See also openethereum/parity-ethereum#7915

@tomaka
Copy link
Member Author

tomaka commented Feb 21, 2019

Once #900 is done, it should be trivial to write an example.

@khimaros
Copy link

@tomaka are there any other blockers?

@tomaka
Copy link
Member Author

tomaka commented Jun 28, 2019

No, libp2p is running just fine from within a browser, provided you use wasm-pack.

The last thing to do would be add an example that is tested on CI, so that we don't accidentally break it.

@tomaka tomaka closed this as completed Jun 28, 2019
@tomaka tomaka reopened this Jun 28, 2019
@tomaka tomaka changed the title Get libp2p-rs to run in the browser Add an example of rust-libp2p running in the browser Jan 10, 2020
@ivoribeiro
Copy link

i would love to see an example of this :D

@govardhangdg
Copy link

Hello! I'd like to take up this issue. I haven't thought of any specific example yet (any ideas/suggestions welcome). I'll figure it out in a few days.
Thanks.

@olanod
Copy link

olanod commented Feb 29, 2020

A chat with the recently added Gossipsub protocol? That's what I'll try soon for my project so you'll be saving me some work 😅

@tomaka
Copy link
Member Author

tomaka commented Mar 2, 2020

To give some hints:

  • By design, WebSockets in the browser can only establish outgoing connections, so you will need to run the browser example against a non-desktop example that listens on WebSockets. Also note that your browser might refuse non-secure WebSockets, so be aware of that.
  • Thanks to Add a js implementation of wasm-ext. #1454, you should be able to do libp2p::wasm_ext::websocket_transport() and obtain an implementation of Transport equivalent to what is in libp2p::ws.
  • Only the low-level transport part needs to be customized for the browser/outside the browser. The rest (including secio/noise/mplex/yamux) is totally cross-platform.

@govardhangdg
Copy link

Thanks @tomaka.

@olanod that seems like a good idea. I'll look into it :)

@govardhangdg
Copy link

@tomaka, what do you mean by "non-desktop" in the previous comment? Do you mean "non-browser", i.e, a node/peer running on a terminal and not in a browser?
So, the browser instances(peers running on browsers) should connect to some peer running on terminal (not on browser as browser doesn't allow incoming websocket connections) and supporting ws transport, is what I understood from it.

@govardhangdg
Copy link

BTW libp2p::wasm_ext::websocket_transport() is not found. I tried to use the latest code (from github) instead of the published crate (0.16.2), but still no luck. Then I tried adding feature "websocket", but I got the error saying that there is no such feature in the rust-libp2p crate.

jrhea pushed a commit to jrhea/rust-libp2p that referenced this issue Apr 18, 2020
Allow application layer to update its enr attestation bitfield
@dt665m
Copy link

dt665m commented Jun 11, 2020

@tomaka I've had a minimum working example of this done a few weeks back. It was based off of the way substrate's browser light node uses the libp2p library. Repo Link. I'd be happy to make a PR if I could get some guidance on how the example should be setup. The linked repo is using vue as the front end but I'd imagine that a plain HTML version would be better for upstream.

@zicklag
Copy link

zicklag commented Jan 15, 2021

@dt665m I would definitely appreciate a browser example! I think a simple plain HTML example would be good, or maybe using Vue would even be fine, if you just used the UMD build of Vue from a CDN so it doesn't require any Webpack setup or anything. There's a super-remote chance I could help if you needed review or other input. I'm really wanting to understand if it's possible to effectively use Rust and libp2p in the Browser and it looks like the answer is yes!

@zicklag
Copy link

zicklag commented Jan 15, 2021

After looking around a bit, it looks like you need a signaling server like a webrtc star server to actually find peers and listen on a websocket, because Browsers can't listen on websockets. I'm not exactly sure what that looks like, but it also looks like I can't get rust-libp2p to actually connect to even a plain js-libp2p node running in the browser, which I would imagine would be a first step.

I'm a little confused, but would appreciate help figuring this out if anybody has any ideas. 😃 I'm wanting to experiment with something like @olanod mentioned: a peer-to-peer chat built on rust-libp2p that can run in the browser.

@MichaelMackus
Copy link

MichaelMackus commented Feb 5, 2021

@zicklag should be possible by using the websocket server as a relay. I'm not too familiar this is supported in the Rust side, but I'd assume so.

There's a separate issue open regarding webrtc, but websockets should work (although like you mentioned, the browser won't be able to actually listen natively).

@mxinden mxinden added help wanted getting-started Issues that can be tackled if you don't know the internals of libp2p very well labels Mar 25, 2022
thomaseizinger referenced this issue in thomaseizinger/rust-libp2p Sep 23, 2022
transports/quic: Muxer and Connection
@mxinden
Copy link
Member

mxinden commented Oct 6, 2022

I am closing here in favor of #2617.

@mxinden mxinden closed this as completed Oct 6, 2022
dkuehr pushed a commit to openmina/rust-libp2p that referenced this issue Oct 24, 2023
dkuehr pushed a commit to openmina/rust-libp2p that referenced this issue Oct 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
difficulty:easy getting-started Issues that can be tackled if you don't know the internals of libp2p very well help wanted priority:nicetohave
Projects
None yet
Development

No branches or pull requests