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

Enable transport over WebSocket (with support of wasm) #491

Open
boxdot opened this issue Nov 12, 2020 · 17 comments
Open

Enable transport over WebSocket (with support of wasm) #491

boxdot opened this issue Nov 12, 2020 · 17 comments
Labels
A-tonic C-request Category: A feature request, i.e: not implemented / a PR.

Comments

@boxdot
Copy link

boxdot commented Nov 12, 2020

I have an experimental implementation of a Connector which allows to tunnel gRPC communication over a WebSocket. This makes it possible to implement a gRPC-over-WebSocket server and more importantly also a client. With small patches of h2 and tower-buffer the client also runs in wasm32.

If you find this useful and my approach as suitable, I would like to discuss how to move forward from here.

Feature Request

Crates

  • tonic (transport module)
  • h2
  • tower-buffer

Motivation

Run gRPC in browser.

Proposal

(High level)

  • Expose the client parts that are independent of TCP and work in wasm as a separate feature.
  • Use this new feature and the new tonic-ws-transport crate to enable implementations of wasm clients.

I am not sure if this should become a separate feature of tonic crate though, or we could do it differently. Due to this bug in cargo (rust-lang/cargo#2524), we might run into problems if we choose conditional compilation based on wasm32 target arch.

Notes:

@LucioFranco
Copy link
Member

Sorry for the delayed response on this!

Is there a spec for gRPC over WS? Beyond gRPC web?

@boxdot
Copy link
Author

boxdot commented Nov 27, 2020

Sorry for the delayed response on this!

Is there a spec for gRPC over WS? Beyond gRPC web?

I don't think so. The idea was just to use websocket as a tunnel for the TCP transport in environments where TCP is not available but websocket is (e.g. browsers). Since gRPC runs on top of HTTP2, and HTTP2 on top of TCP, and my crate allows TCP to run on top of a websocket, it is completely transparent to gRPC.

Actually, I am now also using the tonic-ws-transport crate for an implementation of a websocket->Http2 reverse proxy. Just used the WsConnector in hyper::Server. So, I guess a better name for the crate would be just websocket-tcp-transport.

@LucioFranco
Copy link
Member

Yeah, lets put this on hold to get into tonic, but I want to circle back once I write the new transport and maybe we can get things to fit in so its easy to write this as an external crate.

@boxdot
Copy link
Author

boxdot commented Nov 27, 2020

Sure. Would it be possible to expose the parts of transport that are wasm32 compatible under a feature flag? At least this would allow to use the client in wasm. See boxdot@b06a97d.

@LucioFranco
Copy link
Member

Potentially, I plan to basically extract all the transport stuff so the tonic crate is just a grpc impl. That should make it much easier to get WASM things working with it.

@davidpdrsn davidpdrsn added A-tonic C-request Category: A feature request, i.e: not implemented / a PR. labels Feb 13, 2021
@leobragaz
Copy link

Is there any open branch that's solving this?

@davidpdrsn
Copy link
Member

@bragaz don't think so 😕

@boxdot
Copy link
Author

boxdot commented Mar 9, 2021

I did some work to rebase the branches on top of tokio 1.0 and the latest release of tonic. There is no need for tower's buffer patch anymore, since it is possible to spawn the buffer on any executor (in particular, also on wasm_bindgen_futures) by using this api: https://docs.rs/tower/0.4.6/tower/buffer/struct.Buffer.html#method.pair.

The above implementation is used in the browser with a backend gateway passing websocket streams to a grpc backend for a while already without any problems so far.

I also tried to upstream h2, but there is not much progress there: hyperium/h2#511

@LucioFranco
Copy link
Member

@boxdot this seems reasonable maybe we can try getting into h2 first I see you have an issue but maybe we can talk with @seanmonstar again about it?

@boxdot
Copy link
Author

boxdot commented Apr 14, 2021

@LucioFranco Yes, it makes sense to start with h2, since it is a tiny patch. We just need to figure out how to make it least intrusive. I will pick up the issue there again. Thanks.

@kalcutter
Copy link

Changes for this have been upstreamed to hyper and h2. How should the discussion proceed to make this a reality in tonic?

@boxdot
Copy link
Author

boxdot commented Jun 10, 2021

Changes for this have been upstreamed to hyper and h2. How should the discussion proceed to make this a reality in tonic?

I will upgrade my repository and integrate the latest tonic changes. Then we will hopefully see which minimal changes are needed to tonic.

@LucioFranco
Copy link
Member

Do you have a link to those upstream changes?

@boxdot
Copy link
Author

boxdot commented Jun 11, 2021

h2 got an option to configure the max concurrent reset streams. The non-wasm compatible Instant::now is now only used when it is configured to be > 0. More details here: hyperium/h2#511

The same configuration was exposed in hyper: hyperium/hyper#2535

About my patch of tonic: I introduced a feature flag, which disabled all non-client and os-specific code in transport s.t. it compiles and runs on wasm32-unknown-unknown. This was done before the above patches were merged on version 0.3 of tonic.

@boxdot
Copy link
Author

boxdot commented Jun 16, 2021

I ported my patch to the latest master of tonic: boxdot@1da79d0. It adds a feature flag to tonic which disables all wasm non-compatible parts of transports and enables compilation of generated tonic clients to wasm32. It also avoids using any browser incompatible runtime features.

@LucioFranco If you think that this approach is suitable, I can open a PR.

With this patch it is possible to tunnel any tonic client through a websocket in a browser. Cf. https://github.com/boxdot/tonic-ws-transport/tree/1400e63d578044d1399fb63fa591c52c0502b6d0/examples

@LucioFranco
Copy link
Member

@boxdot Yeah, can you open a PR? I'd like to give this a review (I quickly looked over the code you posted).

lucasmerlin added a commit to lucasmerlin/tonic that referenced this issue Jan 9, 2024
…r in wasm32 targets

This adds a new feature that enables compilation of connect_with_connector and the Endpoint and Channel struct for wasm.

Related: hyperium#491
@domlen2003
Copy link

Since Google updated their plan to only support grpc over WebTransport this issue should maybe closed/reworked?

It would be good for tonic to support WebTransport as an optional transport layer for the server at least. A client implementation could be useful as well tho.

lucasmerlin added a commit to lucasmerlin/tonic that referenced this issue Jun 18, 2024
…r in wasm32 targets

This adds a new feature that enables compilation of connect_with_connector and the Endpoint and Channel struct for wasm.

Related: hyperium#491
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tonic C-request Category: A feature request, i.e: not implemented / a PR.
Projects
None yet
Development

No branches or pull requests

6 participants