专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

详解前端websocket服务器之如何利用扩展优化数据传输速度

ins518 2024-11-18 13:15:21 技术文章 12 ℃ 0 评论

前言

之前的几篇文章介绍了如何搭建websocket服务器,这篇文章我们聊聊如何利用websocket的扩展来做一些事情。

当浏览器向websocket服务器发送连接请求时,服务器可能想要浏览器提供更多的信息,此时Sec-WebSocket-Extensions请求头也就是今天所讲的websocket的扩展就可以派上用场了,下面我们来看一看如何使用这个请求头!

扩展解析规则

Sec-WebSocket-Extensions请求头对应的值拥有一定的规则,这样服务端可以根据这个固定的规则进行解析。

这个请求头对应的值只能由以下字符组成:

// '!', '#', '#39;, '%', '&', ''', '*', '+', '-',
// '.', 0-9, A-Z, '^', '_', '`', a-z, '|', '~'

除此之外,逗号、分号、双引号和等号是特殊字符,有特殊的作用!

我们先看几个demo,大家就能明白它的规则(Sec-WebSocket-Extensions简写为swe),如下:

//demo1
swe: foo

//解析结果
{"foo":[{}]}

//demo2
swe: foo;bar

//解析结果
{"foo":[{"bar":[true]}]}

//demo3
swe: foo;bar;baz

//解析结果
{"foo":[{"bar":[true],"baz":[true]}]}

//demo4
swe: foo;bar=1;baz=2

//解析结果
{"foo":[{"bar":["1"],"baz":["2"]}]}

//demo5
swe: foo;bar=1, qwe;baz=2

//解析结果
{"foo":[{"bar":["1"]}],"qwe":[{"baz":["2"]}]}

//demo6
swe: foo;bar=1, foo;baz=2

//解析结果
{"foo":[{"bar":["1"]},{"baz":["2"]}]}

//demo7
swe: foo;bar="1"

//解析结果
{"foo":[{"bar":["1"]}]}

以上列出7种扩展情况,并且分别给出了服务器解析出的结果,总结规则如下:

  • 解析结果是一个对象,对象是两层结构,如下:
{
	outerKey1: [
 {innerKey: [value,...], ...},
 ...
 ],
 outerKey2: [
 {innerKey: [value,...], ...},
 ...
 ],
 ...
}
  • 逗号分隔第一层;
  • 分号分隔第二层,分号分割后的第一个字符串是结果的第一级属性,剩余的字符串就是对应的第二级属性及其对应的值,如果字符串中有等号,等号前面的字符串是第二级属性,等号后面的字符串就是第二级属性对应的值,如果没有等号,第二级属性对应的值就是true;
  • 等号后面的值加双引号或者不加,效果一样,如demo7;
  • 在每一层级中出现相同的属性,解析时会将它们的值合并在一个数组中,如demo6;

如图1所示是真实浏览器发送的请求,请求头Sec-WebSocket-Extensions的值是permessage-deflate; client_max_window_bits,根据上面的规则服务器可以将其解析成如下形式:

{"permessage-deflate":[{"client_max_window_bits":[true]}]}

压缩/解压websocket传输的数据

图1中Sec-WebSocket-Extensions请求头的值带有deflate、windowBits字样,如果你看了上一篇介绍zlib的文章,你应该能想到此时浏览器想要告知服务器咱俩在通信时可以先将数据进行压缩再发送。

下面我们来看看具体如何实现

第一步服务器获取扩展请求头的值,然后解析,如下:

offers就是服务器通过请求头Sec-WebSocket-Extensions的值最终解析出来的对象,解析之后还需要发送Sec-WebSocket-Extensions响应头。

第二步利用zlib模块对即将发送的数据进行压缩

是否需要压缩以及压缩函数的参数可以通过offers获取,换句话说这些信息都是浏览器通过请求头Sec-WebSocket-Extensions告诉服务器的,浏览器可以通过这个请求头的值来控制服务器的一些行为。此处压缩函数采用createDeflateRaw方法,因为它压缩后的数据没有zlib格式的头尾,节省数据量,这在上一篇文章中介绍过。

待数据压缩完成之后再把数据按照传输协议的格式进行拼装,后面的流程就和《详解前端websocket服务器之数据传输协议》这篇文章介绍的一致了。

第三步利用zlib模块对即接收到的数据进行解压缩

首先按照数据传输协议将数据实体解析出来,传输协议的rsv1位会告知服务器接收到的数据有没有被压缩,如果被压缩了,需要多一步解压操作。

如图4,解压采用和压缩相对的函数createInflateRaw。

综上,websocket服务是否开启解压缩以及解压缩函数的参数都可以通过解析Sec-WebSocket-Extensions请求头来获取。

总结

本文主要介绍了如何利用Sec-WebSocket-Extensions请求头来做解压缩,其实它携带什么样的值,解析规则如何以及利用这些值来做什么,都可以由服务器和客户端自主约定,而不仅仅只能做解压缩!

喜欢我的文章就关注我吧,有问题可以发表评论,我们一起学习,共同成长!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表