29 WebSocket

Posted by CodingWithAlice on May 6, 2021

29 WebSocket

  • 总结

    1、HTTP 的 请求 - 应答 模式不适合开发 实时通信 应用,效率低,难以实现动态页面,所以出现了 WebSocket

    2、WebSocket 是一个 全双工 的通信协议,相当于对 TCP 做了一层薄薄的包装,让它运行在浏览器环境里

    3、WebSocket 使用兼容 HTTP 的 URI 格式 来发现服务,但定义了新的协议名 wswss,端口号也沿用了 80 和 443

    4、WebSocket 使用 二进制帧(也可以发送文本),结构比较简单,数据格式比较轻量,性能开销小,通信高效,特殊的地方是有个 掩码 操作,客户端发数据必须掩码,服务器则不用

    5、WebSocket 利用 HTTP 协议实现连接握手,发送 GET 请求要求协议升级,握手过程中有个非常简单的认证机制,目的是防止误连接 - 握手阶段 采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器

定义

WebSocket 是一种 基于 TCP 的轻量级网络通信协议 – TCP over Web

  • 为什么要有 WebSocket

    其实 WebSocket 与 HTTP/2 一样,都是为了解决 HTTP 某方面的缺陷而诞生的,HTTP/2 针对的是队头阻塞,而 WebSocket 针对的是 请求 - 应答 通信模式。

    目的是在浏览器和服务器之间建立一个不受限的 双向通信 的通道。

  • 为什么传统的 HTTP 协议不能做到 WebSocket 实现的功能?

    因为 HTTP 协议是一个 请求 - 应答 协议,是一种 半双工 的通信模式,虽然可以双向收发数据,但同一时刻只能一个方向上有动作,传输效率低。更关键的一点,它是一种 被动 通信模式, 请求必须先由浏览器发给服务器,服务器只能 被动 响应客户端的请求,无法主动向客户端发送数据

导致 HTTP 难以应用在动态页面、即时消息、网络游戏等要求 实时通信 的领域

特点

1、是一个真正全双工的通信协议,和 TCP 一样,客户端和服务器都可以随时向对方发送数据

2、采用了 二进制帧结构,语法、语义与 HTTP 完全不兼容

3、服务发现方面,WebSocket 没有使用 TCP 的 IP 地址 + 端口号 ,而是延用了 HTTP 的 URI 格式,协议名为 ws - 明文 / wss - 加密 的 WebSocket 协议

4、默认端口也选择了 80 和 443(防火墙屏蔽了绝大多数的端口)

5、没有同源限制,客户端可以与任意服务器通信

握手

imgimg

握手是一个标准的 HTTP GET 请求,但要带上两个 协议升级 的专用头字段:

  • Connection: Upgrade:表示要求 协议升级
  • Upgrade: websocket:表示要升级成 WebSocket 协议

握手消息还增加了两个额外的 认证用头字段(所谓的挑战,Challenge):

  • Sec-WebSocket-Key:一个 Base64 编码的 16 字节随机数,作为简单的认证密钥;
  • Sec-WebSocket-Version:协议的版本号,当前必须是 13

image-20210506173737825

WebSocket握手响应报文 也是有特殊格式的,要用字段 Sec-WebSocket-Accept 验证客户端请求报文,同样也是为了防止误连接 - 状态码为101 Switching Protocols

HTTP/1.1 101 Switching Protocols
Server: WebSockify Python/2.6.6
Date: Wed, 27 May 2020 03:03:21 GMT
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: hXXXXXXXXXXXXXXxGmM=
Sec-WebSocket-Protocol: binary

握手成功后,通信不再使用 HTTP 协议,而采用 WebSocket 独立的数据帧

  • 浏览器用 wss://xxx 创建 WebSocket 连接时,会先通过 HTTPS 创建安全的连接,然后,该 HTTPS 连接升级为 WebSocket 连接,底层通信走的仍然是安全的 SSL/TLS 协议