json WebSocket 如何压缩消息?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19298651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 19:53:00  来源:igfitidea点击:

How does WebSocket compress messages?

javascriptjsonwebsocketsocket.io

提问by MaiaVictor

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?

JSON.stringify 显然不是很节省空间。例如,[123456789,123456789] 占用 20 多个字节,而它可能只需要大约 5 个字节。 websocket 在发送到流之前是否压缩其 JSON?

回答by Joakim Erdfelt

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

从本质上讲,WebSocket 只是一组文本或二进制数据的框架。

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).

然而,WebSocket 规范允许扩展,并且已经有多种压缩扩展(其中之一的正式规范已经完成)。

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

截至今天(2018 年 8 月),公认的压缩规范是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)
  • permessage-deflate- 使用 deflate 压缩整个消息的正式规范的名称,而不管 websocket 帧的数量。
  • x-webkit-deflate-frame- 一种早期提议的压缩,用于压缩每个原始 websocket 数据帧。在 Chrome 和 Safari 中使用。(现在已在 Chrome 和 Safari 中弃用)
  • perframe-deflate- 上述压缩的重命名版本。被各种 websocket 服务器实现所使用,也曾短暂地出现在各种基于 WebKit 的客户端中。(在现代浏览器中完全弃用,但仍然出现在各种 WebSocket 客户端库中)

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

值得注意的是,permessage-deflate扩展是在一个线PMCE(每消息压缩扩展)的第一,最终将包括其它压缩方案(正在讨论那些permessage-bzip2permessage-lz4permessage-snappy

回答by Myst

Does websocket compress its JSONs before sending to stream?

websocket 是否在发送到流之前压缩其 JSON?

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.

正如 Joakim Erdfelt 恰当地指出的那样,Websocket 连接支持文本和二进制消息。

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).

JSON 只是传输数据的一种方式,具有通用性和易用性的优点(但就空间而言是浪费的)。

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').

您可以使用 Websocket API 轻松传输二进制数据,以牺牲其他问题(例如endieness、字长、解析等)为代价来消除带宽开销。

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

许多浏览器还支持 Websocket 消息压缩作为 Websocket 协议的扩展(尽管服务器可能不支持该扩展)。

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

使用Sec-WebSocket-ExtensionsHTTP 标头协商扩展。协商通常由客户端/服务器实现,而不提供公共 API 来控制它们。

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

直到 2015 年,还有许多方法和实现,但自 2015 年 12 月以来,RFC 7692 是消息压缩的唯一真正竞争者,事情变得更加清晰。

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.

RFC 7692 在将整个消息包装(可能是分段)之前压缩整个消息,使其比以前的一些压缩方案更容易实现。

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

当前草案提供了permessage-foo压缩协商方案(foo请求/支持的压缩在哪里)。

I only experienced the permessage-deflateextension myself.

我只是permessage-deflate自己体验了扩展。

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...

此外,RFC 7692 支持选择性压缩,这意味着某些消息可能会被压缩,而另一些则不会被压缩......

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

...例如,[123456789,123456789]可能会按原样发送,因为它的长度表明它可能不值得进行压缩工作。

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

支持permessage-deflate(RFC 7692),2017 年 8 月 8 日:

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

这是评论中信息的组合,最后更新于 2017 年 8 月 8 日。

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
  • 自 32 年以来的铬
  • 自 37 年以来的 Mozilla Firefox
  • Safari - 不受支持(10.1.2 似乎使用x-webkit-deflate-frame
  • Microsoft Edge - 从版本 40 起不受支持

Known Server Support

已知服务器支持

回答by SLaks

Websockets send raw bytes.
They don't know or care what those bytes represent.

Websockets 发送原始字节。
他们不知道也不关心这些字节代表什么。

If you want to compress data, you'll need to compress it yourself before sending it down the wire.

如果你想压缩数据,你需要在发送之前自己压缩它。

Note that Chrome supports gzip for websocket connections. (assuming your server also does)

请注意,Chrome 支持 gzip 用于 websocket 连接。(假设您的服务器也这样做)