Question

First off - I understand SPDY and Websockets aren't the same thing, and that you can run Websockets over SPDY like you can with HTTP, etc.

However - I am wondering if SPDY would be a viable replacement for websockets if I am trying to provide a REST (like) API that also supports server push (bi-directional calls over the same connection).

My current prototype uses websockets (node+socket.io), and works fine. However, my issue with websockets is I am having to dream up my own JSON protocol for routing requests both to and from the server. I'd much rather use REST-style URIs and Headers in requests, which fits better in a REST-based architecture. SPDY seems like it would support this better.

Also, because of the lack of headers, I'm concerned websockets won't fit well in our deployment network, and thinking SPDY would be a better fit again.

However, I've not seen many examples of bidirectional SPDY requests, apart from pushing files to the browser. I would like to push events and data to the browsers, such as:

Content-Type: application/json
{
   "id": "ca823f3e233233",
   "name": "Greg Brady"
}

but it's not clear to me how the browser/Javascript might "listen" and react to these, as I would with the WebSocket and socket.io APIs.

Was it helpful?

Solution

Let's start from the beginning: why would you want to run WebSockets over SPDY, as opposed to doing an HTTP upgrade? If you upgrade an HTTP connection to WS, then nothing else can use that TCP stream - the WS connection can be idle, but the connection is blocked nonetheless. With SPDY, you can mux multiple requests/responses, and a websocket connection (or even multiple) over the same underlying TCP stream. On a practical note, as of July 2012, WS over SPDY is still a work in progress, so you will have to wait to use SPDY for WebSockets - hopefully not too long though!

But let's assume the support is there... The reason why it's not clear how to listen for "SPDY Push" from JavaScript is because there is no way to do that! A pushed resource goes into your browsers cache - nothing more, nothing less. If you need to stream data to your javascript callbacks, then WebSockets, or Server-Sent Events (SSE) is the answer.

So, putting it all together:

  • HTTP adds a lot of overhead for individual small requests (headers, etc)
  • WebSockets gives you a low overhead channel, but requires you implement own routing
  • SPDY will significantly reduce the overhead and cost of small HTTP requests (win)
  • SSE is a good, simple alternative to pushing data to the client (which works today, over SPDY)

You could use SPDY+SSE to meet your goals, and all of that communication can run over the same TCP channel. SPDY requests to the server, SSE push from the server.

OTHER TIPS

First some clarifications:

  • The base WebSocket protocol (IETF 6455) is not layered onto HTTP. The initial handshake for WebSocket connections is HTTP compatible, but once the handshake is completed, the protocol is a framed, bi-directional full-duplex connection with very low overhead (often just 2 bytes per frame of header).

  • The WebSocket over SPDY idea is a proposal that may or may not see the light of day. In this case, WebSocket is in fact being layered on SPDY. The initial connection/handshake may happen faster due to the nature of SPDY versus HTTP, however, the data frames will have more overhead because the WebSocket header fields are mapped into SPDY header fields.

SPDY aims to be a more efficient replacement for HTTP. WebSocket is an entirely different beast that enables very low-latency bi-directional/full-duplex messaging between the client and server.

If what you are interested in server-push with a simple API and you don't need super low-latency, then you might consider server-sent events which has an API that is simple and similar to the WebSocket API. Or you could look into one of the many good Comet libraries which enable server-push but will better support old browsers unlike any of the above solutions.

However, my issue with websockets is I am having to dream up my own JSON protocol for routing requests both to and from the server.

I wrote a thin RPC layer over socket.io wrapping network calls in promises just for that reason. You can take a peek at it here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top