你了解WebSocket吗?

1.写在前面

前面的博客已经介绍完了HTTP1.0/1.1相关的协议了,这个时候我们继续来了解对应的WebSocket协议

2.Websocket解决什么问题?

如何及时获得更新?从轮询到通知

在这里插入图片描述

Chrome请求列表:分析WebSocket

  • 过滤器
    • 按类型:WS
    • 属性过滤:is:running
  • 表格列
    • Data:消息负载。如果消息为纯文本,则在此处显示。对于二进制操作码,此列将显示操作码的名称和代码。支持以下操作码:Continuation Frame、Binary Frame、Connection Close Frame、Ping Frame 和Pong Frame
    • Length:消息负载的长度(以字节为单位)
    • Time:收到或发送消息的时间
  • 消息颜色
    • 发送至服务器的文本消息为浅绿色
    • 接收到的文本消息为白色
    • WebSocket操作码为浅黄色
    • 错误为浅红色

支持双向通讯的WebSocket

  • Rfc6455(2011.12)

  • 双向细通讯的优劣?

  • 如何管理会话?

  • 如何维持长连接?

  • 兼容HTTP协议 端口复用

  • 支持扩展 如permessage-deflate扩展

    在这里插入图片描述

3.Websocket的约束

WebSocket的成本

  • 实时性与可伸缩性

    • 牺牲了简单性
  • 网络效率与无状态:请求2基于请求1

    • 牺牲了简单性与可见性

    在这里插入图片描述

在这里插入图片描述

长连接的心跳保持

  • HTTP长连接只能基于简单的超时(常见为65秒)
  • WebSocket连接基于ping/pong心跳机制维持。

兼容HTTP协议

  • 默认使用80或者443端口
  • 协议升级
  • 代理服务器可以简单支持

在这里插入图片描述

设计哲学:在Web约束下暴露TCP给上层

  • 元数据去哪了?
    • 对比:HTTP协议头部会存放元数据
    • 由WebSocket上传输的应用层存放元数据
  • 基于帧:不是基于流(HTTP、TCP)
    • 每一帧要么承载字符数据,要么承载二进制数据
  • 基于浏览器的同源策略模型(非浏览器无效)
    • 可以使用Access-Control-Allow-Origin等头部
  • 基于URI、子协议支持同主机同端口上的多个服务

4.WebSocket协议格式

帧格式示意图

  • 红色是2字节必然存在的帧首部

    在这里插入图片描述

数据帧格式:RSV保留值

  • RSV1/RSV2/RSV3:默认为0,仅当使用extension扩展时,由扩展决定其值

    在这里插入图片描述

数据帧格式:帧类型

  • 持续帧

    • 0:继续前一帧
  • 非控制帧

    • 1:文本帧(UTF8)
    • 2:二进制帧
    • 3-7:为非控制帧保留
  • 控制帧

    • 8:关闭帧
    • 9:心跳帧ping
    • A:心跳帧pong
    • B-F:为控制帧保留

    在这里插入图片描述

ABNF描述的帧格式

在这里插入图片描述

5.如何从HTTP升级到WebSocket

URI格式

  • Ws-URI = “ws:” “//” host [“:” port] path [“?” query]
    • 默认的port端口80
  • Wss-URI = “wss:” “//” host [“:” port] path [“?” query]
    • 默认port端口443
  • 客户端提供信息
    • host与port:主机名和端口
    • Shema:是否基于SSL
    • 访问资源:URI
    • 握手随机数:Sec-WebSocket-Key
    • 选择子协议:Sec-WebSocket-Protocol
    • 扩展协议:Sec-WebSocket-Extensions
    • CORS跨域:Origin

建立握手

在这里插入图片描述

如何证明握手被服务器接受?预防意外

  • 请求中的Sec-WebSocket-Key随机数
    • 例如Sec-WebSocket-Key: A1EEou7Nnq6+BBzoAzqWlg==
  • 响应中的Sec-WebSocket-Accept证明值
    • GUID(RFC4122):258EAFA5-E914-47DA-95CA-C5AB0DC85B11
    • 值构造规则:BASE64(SHA1(Sec-WebSocket-KeyGUID))
      • 拼接值:A1EEou7Nnq6+BBZoAZqWlg==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
      • SHA1 值:713f15ece2218612fcadb1598281a35380d1790f
      • BASE 64 值:cT8V7OIhhhL8rbFZgoGjU4DReQ8=
      • 最终头部:Sec-WebSocket-Accept: cT8V7OIhhhL8rbFZgoGjU4DReQ8=

6.传递消息时的编码格式

消息与数据帧

  • Message消息
    • 1条消息由1个或者多个帧组成,这些数据帧属于同一类型
    • 代理服务器可能合并、拆分消息的数据帧
  • Frame数据帧
    • 持续帧
    • 文本帧、二进制帧

非控制帧的消息分片:有序

在这里插入图片描述

数据帧格式:消息内容的长度

  • 消息内容长度组成

    • 应用消息长度
    • 扩展数据长度
  • <=125字节

    • 仅使用Payload len
  • 126至2^16-1

    • Payload len 值为126
    • Extended payload length16为表示长度
  • 216至264-1

    • Payload len值为127
    • Extended payload length共8字节64位表示长度

    在这里插入图片描述

发送消息

  • 确保WebSocket会话处于OPEN状态
  • 以帧来承载消息,一条消息可以拆分多个数据帧
  • 客户端发送的帧必须基于掩码编码
  • 一旦发送或者接收到关闭帧,连接处于CLOSING状态
  • 一旦发送了关闭帧,且接收到关闭帧,连接处于CLOSED状态
  • TCP连接关闭后,WebSocket连接才完全被关闭

7.掩码及其所针对的代理污染攻击

针对代理服务器的缓存污染攻击

在这里插入图片描述

frame-masking-key掩码

  • 客户端消息:MASK为1(包括控制帧)传递32位无法预测的、随机的Masking-key

  • 服务器端消息:MASK为0

    在这里插入图片描述

掩码如何防止缓存污染攻击?

  • 目的:防止恶意页面上的代码,可以经由浏览器构造出合法的GET请求,使得代理服务器可以识别出请求并缓存响应。
  • 强制浏览器执行以下方法:
    • 生成随机的32位frame-masking-key,不能让JS代码猜出(否则可以反向构造)
    • 对传输的包体按照frame-masking-key执行可对称解密的XOR异或操作,使代理服务器不识别
    • 消息编码算法:
      • j = i MOD 4
      • Transformed-octet-i = original-octet-i XOR masking-key-octet-j

8.如何保持会话心跳

心跳帧

  • 心跳帧可以插在数据帧中传输
    • ping帧
      • opcode=9
      • 可以含有数据
    • pong帧
      • opcode=A
      • 必须与ping帧数据相同

在这里插入图片描述

9.如何关闭WebSocket会话

关闭会话的方式

  • 控制帧中关闭帧:在TCP连接之上的双向关闭

    • 发送关闭帧后,不能再发送任何数据
    • 接收到关闭帧后,不再接收任何到达的数据
  • TCP连接意外中断

关闭帧格式

  • opcode=8

  • 可以含有数据,但仅用于解释关闭会话的原因

    • 前2字节为无符号整型

    • 遵循mask掩码规则

      在这里插入图片描述

关闭帧的错误码

错误码 含义
1000 正常关闭
1001 表示浏览器页面跳转或者服务器将要关机
1002 发现协议错误
1003 接收到不能处理的数据帧(例如某端不能处理二进制消息)
1004 预留
1005 预留(不能用在关闭帧里)期望但没有接收到错误码
1006 预留(不能用在关闭帧里)期望给出非正常关闭的错误码
1007 消息格式不符合opcode(例如文本帧里消息没有用UTF8编码)
1008 接收到的消息不遵守某些策略(比1003、1009更一般的错误)
1009 消息超出能处理的最大的长度
1010 客户端明确需要使用扩展,但服务器没有给出扩展的协商信息
1011 服务器遇到未知条件不能完成请求
1015 预留(不能用在关闭帧里),表示TLS握手失败

10.写在最后

这篇博客对WebSocket协议进行一个简单的介绍,后面我们会继续介绍对应的HTTP2的协议

猜你喜欢

转载自blog.csdn.net/qq_36434742/article/details/125165830