Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does WebSocket compress messages?

JSON.stringify is obviously not very space efficient. For example, [123456789,123456789] occupy 20+ bytes when it could need just around 5. Does websocket compress its JSONs before sending to stream?

like image 582
MaiaVictor Avatar asked Oct 10 '13 14:10

MaiaVictor


People also ask

Does WebSocket use compression?

WebSocket is, at its heart, just a set of framing for TEXT or BINARY data. It performs no compression on its own.

Can WebSocket messages get lost?

Websocket client connections may drop due to intermittent network issue and when connections drop, messages will also be lost. In a pubsub system, publishers are decoupled from subscribers, so publishers hard to detect subscribers' drop or message loss.

Why WebSockets are not scalable?

But why are WebSockets hard to scale? The main challenge is that connections to your WebSocket server need to be persistent. And even once you've scaled out your server nodes both vertically and horizontally, you also need to provide a solution for sharing data between the nodes.

Does WebSockets scale?

Compared to REST, WebSockets allow for higher efficiency and are easier to scale because they do not require the HTTP request/response overhead for each message sent and received. Furthermore, the WebSocket protocol is push-based, enabling you to push data to connected clients as soon as events occur.


2 Answers

WebSocket is, at its heart, just a set of framing for TEXT or BINARY data.

It performs no compression on its own.

However, the WebSocket spec allows for Extensions, and there have been a variety of compression extensions in the wild (the formalized specs for one of these is finalized).

As of today (August 2018) the accepted compression spec is permessage-deflate.

Some of the extensions seen in the wild:

  • permessage-deflate - the name of the formalized spec for using deflate to compress entire messages, regardless of the number of websocket frames.
  • x-webkit-deflate-frame - an early proposed compression that compresses each raw websocket data frame. Seen in use by Chrome and Safari. (now deprecated in Chrome and Safari)
  • perframe-deflate - a renamed version of the above compression. Seen in use by various websocket server implementations, and also briefly showed up in various WebKit based clients. (Completely deprecated in modern browsers, but does still show up in various WebSocket client libraries)

Of note, the permessage-deflate extension is the first in a line of PMCE (Per-Message Compression Extensions) that will eventually include other compression schemes (ones being discussed are permessage-bzip2, permessage-lz4, and permessage-snappy)

like image 64
Joakim Erdfelt Avatar answered Sep 24 '22 06:09

Joakim Erdfelt


Does websocket compress its JSONs before sending to stream?

The short answer is: sometimes, but you can't depend on it.

As stated aptly by Joakim Erdfelt, Websocket connections support both Text and Binary messages.

JSON is just one way to transport data, with the advantage of versatility and ease of use (while being wasteful as far as space is concerned).

You can easily transfer binary data using the Websocket API, eliminating bandwidth overhead at the expense of other concerns (such as endieness, word length, parsing, etc').

Many browsers also support Websocket message compression as an extension to the Websocket protocol (although the server might not support the extension).

Extensions are negotiated using the Sec-WebSocket-Extensions HTTP header. The negotiations are usually implemented by the client / server without offering a public API to control them.

Right up until 2015, there were a number of approaches and implementations in the wild, but since December 2015 RFC 7692 is the only real contender for message compression and things are much clearer.

RFC 7692 compresses the whole message before wrapping (and perhaps fragmenting) it in Websocket "packets", making it easier to implement than some previous compression schemes.

The current draft offers a permessage-foo compression negotiation scheme (where foo is the requested / supported compression).

I only experienced the permessage-deflate extension myself.

Do notice that extension negotiations are optional, meaning that potential network clients are usually allowed to negotiate connections without compression, even if your server supports the extension.

Moreover, RFC 7692 supports selective compression, meaning some messages might be compressed while others aren't compressed...

... for example, [123456789,123456789] might be sent as is, since it's length indicates it isn't likely to be worth the compression effort.

Support for permessage-deflate (RFC 7692), August 8th, 2017:

This is a combination of the information in the comments, last updated August 8th, 2017.

If I missed anything, add them here and update the date.

Known Browser Support

  • Chrome since 32
  • Mozilla Firefox since 37
  • Safari - unsupported (10.1.2 seems to use x-webkit-deflate-frame)
  • Microsoft Edge - unsupported as of version 40

Known Server Support

  • Crossbar.io (Autobahn)
  • wspy
  • Tornado
  • Faye on node.js and Ruby
  • SwiftWebSocket (read only?)
  • WS-RS (Rust)
like image 41
Myst Avatar answered Sep 24 '22 06:09

Myst