back

by anderspitman·7y ago·view on hn ↗
I'm quite surprised they're not using websockets for streaming. Anyone know why?

EDIT: Better question: is anyone aware of a system like gRPC but built with bidirectional streaming for the browser from the beginning?

5 comments
I think you've unwittingly asked for DDP and Meteor.

Meteor was seriously ahead of its time, much like all good systems that suffered under their complexity before the infrastructure was there to support it. At its core, its a websocket-based RPC protocol that could return database cursors, with asynchronous downloading of database documents. The client ran a miniature instance of MongoDB inside the browser, which enabled clients to issue normal MongoDB queries client-side with optimistic evaluation. Data updates would hit the local mongo instance, be optimistically rendered, and then be sent to the server. Then the source-of-truth would be delivered back to the client via the mongodb oplog.

In other words, it's bi-directional mongodb oplog streaming. Absolutely fantastic considering it was released in 2012.

Websockets have head-of-line blocking, which is one of the main reasons HTTP/2 exists.

HTTP/2 (i.e. gRPC) is a bidirectional streaming protocol, and you can use the fetch API in JS to use it. The reason gRPC-web exists is because browsers artificially hide some of the headers, which have been part of the HTTP standard since the beginning. If that was fixed, gRPC would just be plain XHR or fetch requests and gRPC-web would go away.

I'm the author of this blog post and one of the maintainers of the Improbable grpc-web implementation.

I don't explicitly mention it in the post, but no browser has support for fetch request streaming yet, so true bidirectionality would not be possible even if you had control over the headers. This will come eventually, and then grpc-web will have proper bi-di streaming support. It is doubtful whether it will actually have access to raw HTTP/2 frames which would be required for the gRPC HTTP/2 protocol.

Correct me if I'm wrong, but my understanding is that HTTP/2 only half solves the head of line blocking problem. It's true that you don't have message-level blocking like websockets, but it's still TCP so streams can block each other if there's packet loss. QUIC seems like the full solution.

Also, is head of line blocking really that big of a problem for RPC? It only seems to really be a big deal if your latency tolerance is really tight.

Check out WAMP? It's websockets + RPC.

http://wamp.ws

And a server that implements it:

http://crossbar.io https://github.com/crossbario/autobahn-js

Both protocols implement their own framing scheme(s). Once you start looking at the details of such a suggestion, it becomes kind-of a hack to use websockets for streaming gRPC and likely to have scaling issues. One can do it as a proof-of-concept and may work fine in low-traffic scenarios. I think it will not be a reality until browsers expose some sort of fetch-like http2 primitive to developers.
I guess a more implicit part of my question is why didn't they design it to work well on top of websockets from the beginning, rather than doing their own framing? If you assume you have a reliable in-order messaging protocol to build on top of, then you can swap that protocol out for different cases (ie websockets/WebRTC on the web, reliable UDP/SCTP/etc for other cases). I say this with very little background in gRPC. I'm working on a protocol that aims to do exactly this[0] (but for streaming only, not RPC), and I'd like to learn as much as possible from smarter people who have done similar projects.

[0] https://github.com/anderspitman/omnistreams-spec

Improbable's client does have experimental websocket streaming.