Alan's blog Alan's blog
首页
思考感悟
技术学习
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Alan wu

前端小时
首页
思考感悟
技术学习
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 计算机基础

  • 架构设计

  • HTTP网络

    • 关于前后端鉴权的几种方式
    • DNS与ARP的关系与原理解析
    • POST本质区别,面试官想听什么
    • TCP的可靠性传输是如何保证的
    • HTTP 2.0有什么新特性
    • 面试官:讲一下 https 和 http 的区别
    • 如何使用JWT做简单的登录验证操作
    • 密码学家的工具箱
    • 一文读懂TCP和UDP的区别
    • Web前端安全知多少
    • WebSocket 协议系统解析
      • 01 前言
      • 02 webSocket
      • 03 通信原理
      • 04 心跳包
      • 05 应用场景
      • 06 与HTTP的异同
        • 相同点
        • 不同点
      • 07 小结
  • Node

  • 小程序

  • 设计

  • JavaScript

  • HTML&CSS

  • 浏览器

  • webpack

  • 运维

  • Vue&React

  • 技术
  • HTTP网络
alanwu
2020-03-08
目录

WebSocket 协议系统解析

# WebSocket 协议系统解析

读书之法, 在循序而渐进, 熟读而精思

# 01 前言

早期的网站使用的是轮询技术,用来实现定时请求资源,由客户端发送HTTP请求。但是这种请求可能存在很长的http请求头,真正的数据可能很少,这就造成了带宽的消耗。现在比较新的技术是Comet,可以实现全双工通信,但也需要反复发出请求,而且HTTP长连接在Comet中是普遍使用的,也会消耗服务器资源。

所以为了解决上面的情况,HTML5定义了WebSocket协议,能够更好地节约服务器资源和带宽,并且能够实现实时通讯。

# 02 webSocket

WebSocket与HTTP和HTTPS使用的是相同的TCP端口,由于这个的原因,可以绕过大多数的防火墙限制。默认是使用80端口,但是在TLS协议的时候会使用443端口。具体实现上是通过http协议建立通道,然后在此基础上用真正的WebSocket协议进行通信,所以WebSocket协议和http协议是有一定的交叉关系的。

该协议最大的特点是实现了服务端推送,以往获取资源只能由客户端发起,现在服务端可以主动发起了。实现了真正的全双工通信。它有以下的优点:

  • 较少的控制开销
  • 更强的实时性
  • 能够保持长连接
  • 更好的二进制支持
  • 可以支持扩展
  • 能够压缩数据提高效率
  • 没有同源限制

# 03 通信原理

当客户端与服务端建立WebSocket连接,在客户端与服务端的握手过程中,客户端会先发送一个HTTP请求,包含一个Upgrade请求头来告诉服务端要升级为WebSocket协议。

let ws = new WebSocket('ws://localhost:9000');//建立连接
1

发送请求头:

Host: localhost:9000
Origin: http://localhost:9000
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: 5fTJ1LTuh3RKjSJxydyifQ== // 与响应头 Sec-WebSocket-Accept 相对应
Sec-WebSocket-Version: 13    // 表示 websocket 协议的版本
Upgrade: websocket    // 表示要升级到 websocket 协议
1
2
3
4
5
6
7

响应头:

Connection: Upgrade
Sec-WebSocket-Accept: ZUip34t+bCjhkvxxwhmdEOyx9hE=
Upgrade: websocket
1
2
3

此时如果正常,服务器就会返回101状态码并切换为WebSocket协议建立全双工连接,后续信息将会通过这个协议进行传输。

GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; //  一个固定的字符串
accept = base64(sha1(key + GUID));    
// key 就是 Sec-WebSocket-Key 值,
//accept 就是 Sec-WebSocket-Accept 值
1
2
3
4

Sec-WebSocket-Key:客户端随机生成的一个base64编码

Sec-WebSocket-Accept:服务端经过算法处理后回传给客户端

Connection和Upgrade字段告诉服务器,客户端发起的是WebSocket协议请求

最后一步客户端拿到服务端的值之后使用相同算法进行解码之后,跟服务端的进行对比,如果一致则成功连接。

function connectWebsocket() {
    ws = new WebSocket('ws://localhost:9000');
    // 监听连接成功
    ws.onopen = () => {
        console.log('连接服务端WebSocket成功');
        // send 方法给服务端发送消息
        ws.send(JSON.stringify(msgData));    
    };

    // 监听服务端消息(接收消息)
    ws.onmessage = (msg) => {
        let message = JSON.parse(msg.data);
        console.log('收到的消息:', message)
        elUl.innerHTML += `<li class="b">小秋:${message.content}</li>`;
    };

    // 监听连接失败
    ws.onerror = () => {
        console.log('连接失败,正在重连...');
        connectWebsocket();
    };

    // 监听连接关闭
    ws.onclose = () => {
        console.log('连接关闭');
    };
};
connectWebsocket();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 04 心跳包

当连接后长时间不进行通信就可能会出现连接不稳定的情况,那么就会影响数据的传输,比如在聊天室的信息可能出现不同步的情况。所以客户端会定时发送一个包告诉服务器我连接正常,服务器也会回应正常。称之为心跳包。

setInterval(() => {    ws.send('这是一条心跳包消息');}, 60000)
1

# 05 应用场景

WebSocket协议多用于实时通讯方面的场景,对实时数据要求比较高的,可以应用于以下的场景:

  • 即时聊天通信
  • 多玩家游戏
  • 在线协同编辑/编辑
  • 实时数据流的拉取与推送
  • 体育/游戏实况
  • 实时地图位置

# 06 与HTTP的异同

# 相同点
  • 都是基于TCP的应用层协议;
  • 都使用Request/Response模型进行连接的建立;
  • 在连接的建立过程中对错误的处理方式相同,在这个阶段WS可能返回和HTTP相同的返回码;
  • 都可以在网络中传输数据。
# 不同点
  • WS使用HTTP来建立连接,但是定义了一系列新的header域,这些域在HTTP中并不会使用;
  • WS的连接不能通过中间人来转发,它必须是一个直接连接;
  • WS连接建立之后,通信双方都可以在任何时刻向另一方发送数据;
  • WS连接建立之后,数据的传输使用帧来传递,不再需要Request消息;
  • WS的数据帧有序。

# 07 小结

WebSocket可写的东西还挺多,比如WebSocket扩展。客户端、服务端之间是如何协商、使用扩展的。WebSocket扩展可以给协议本身增加很多能力和想象空间,比如数据的压缩、加密,以及多路复用等。理论还是要联系实际才可以。

参考文章

  • WebSocket教程 阮一峰博客
  • 深入剖析WebSocket的原理
  • WebSocket详解(四):刨根问底HTTP与WebSocket的关系
  • 维基百科 WebSocket
  • WebSocket 原理浅析与实现简单聊

编辑 (opens new window)
上次更新: 2023/05/13, 23:08:05
Web前端安全知多少
Node.js之Buffer对象浅析

← Web前端安全知多少 Node.js之Buffer对象浅析→

最近更新
01
HTTPS:让数据传输更安全
06-15
02
沙盒:页面和系统之间的隔离墙
06-15
03
CSRF攻击:陌生链接不要随便点
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2023 Alan Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式