Open boxdot opened 3 years ago
Sorry for the delayed response on this!
Is there a spec for gRPC over WS? Beyond gRPC web?
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
.
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.
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 https://github.com/boxdot/tonic/commit/b06a97dc563eb41f3ff7f4399befd7d872dae090.
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.
Is there any open branch that's solving this?
@bragaz don't think so 😕
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: https://github.com/hyperium/h2/issues/511
@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?
@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.
Changes for this have been upstreamed to hyper and h2. How should the discussion proceed to make this a reality in tonic?
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.
Do you have a link to those upstream changes?
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: https://github.com/hyperium/h2/issues/511
The same configuration was exposed in hyper
: https://github.com/hyperium/hyper/pull/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.
I ported my patch to the latest master of tonic: https://github.com/boxdot/tonic/commit/1da79d033b50ab08495ccbdfe287278a6192921e. 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
@boxdot Yeah, can you open a PR? I'd like to give this a review (I quickly looked over the code you posted).
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.
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.tonic
: https://github.com/boxdot/tonic/commit/b06a97dc563eb41f3ff7f4399befd7d872dae090h2
: https://github.com/boxdot/h2/commit/03838652b2b2a40c46df44a8299ebc1a9236939ctower-buffer
: https://github.com/boxdot/tower/commit/1091340a3eb106da844348bc1b1ef7ce7b4a763dIf you find this useful and my approach as suitable, I would like to discuss how to move forward from here.
Feature Request
Crates
Motivation
Run gRPC in browser.
Proposal
(High level)
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 (https://github.com/rust-lang/cargo/issues/2524), we might run into problems if we choose conditional compilation based onwasm32
target arch.Notes:
tokio
0.2 branch.