WebSocket 协议与 HTTP 协议、定时轮询技术、长轮询技术
目录
- 1 为什么需要 WebSocket?
- 2 WebSocket
- 2.1 采用 TCP 全双工
- 2.2 建立 WebSocket 连接
- 2.3 WebSocket 帧
- 3 WebSocket 解决的问题
- 3.1 HTTP 存在的问题
- 3.2 Ajax 轮询存在的问题
- 3.3 长轮询存在的问题
- 3.4 WebSocket 的改进
参考资料:
- 为什么有 http 还要有 websocket - BiliBili
- WebSocket - CSDN
1 为什么需要 WebSocket?
在使用 HTTP 协议时,用户点击网页上的按钮,客户端发送一次请求,服务器返回一次响应,如下图所示。不难发现,服务器从来都不会主动向客户端发送一次请求。
因此在 HTTP 协议中,客户端是主动方,服务器是被动方。
考虑网页游戏的场景,通常情况下玩家不需要点击鼠标,怪物就能够源源不断地刷新出来。也就是说,在用户不做任何操作的情况下,客户端能够收到消息并发生变更。那么这种看起来像是服务器主动发送消息给客户端的场景是如何实现的呢?
何谓 “看起来像是”?答:在定时轮询和长轮询中,仍然是客户端主动发送请求,只是用户感知不到,误以为是服务器在主动发送数据。
最常见的做法是「HTTP 定时轮询」,客户端定时自动发送 HTTP 请求到服务器,服务器收到请求后对客户端进行响应,如下图所示。这是一种「伪服务器推」的形式,它其实并不是服务器主动发送消息到客户端,而是客户端不断请求服务器,只是用户无感知而已。
使用该方式的场景很多,最常见的就是扫码登录。比如微信的登录平台,前端网页不知道用户是否完成扫码,于是不断向后端服务器询问,如下图所示。一般请求间隔是在 1 到 2 秒之间,保证用户在扫码后的 1 到 2 秒中能够得到反馈。
以上便是「HTTP 定时轮询」,它的缺点在于:
- 每次请求消耗带宽,增加了下游服务器的负担;
- 最快情况下,用户也需要等待 1 到 2 秒才能触发下一次 HTTP 请求,完成页面的跳转。
说明:由于服务器是被动方,即使它知道用户扫码成功了也没办法主动告诉客户端,需要等待客户端的下一次请求,因此用户需要等待 1 到 2 秒才能完成页面的跳转。
更好的方案是「HTTP 长轮询」,如下图 (b) 所示。HTTP 请求发送后一般会留一定的时间给服务器做响应,比如 3 秒,规定时间内没有返回就是超时。如果增大超时的时间,比如 30 秒,在这 30 秒内,只要服务器收到了用户的扫码请求,就可以立马返回给客户端。如果超时,那么客户端就立马发起下一次请求。
说明:HTTP 协议的通信模式是一个请求搭配一个响应,即一问一答的模式。在定时轮询中,即使服务器知道了答案,但只要客户端没问,它就不能答。而在长轮询中,客户端提问后服务器并不急着回答,以避免浪费本次提问,从而保证了一旦服务器知道了答案就能立即进行回答。
这样就减少了 HTTP 请求的个数,并且响应也是及时的。采用该方案的有百度网盘,如下图所示:
2 WebSocket
上述两种解决方案,本质上还是客户端主动取数据,适用于扫码登录这种简单的应用场景。而网页游戏中有大量的数据需要由服务器主动推送到客户端,这就需要使用 WebSocket 技术了。
2.1 采用 TCP 全双工
维基百科
- 半双工:半双工的系统允许二台设备之间的双向资料传输,但不能同时进行。因此同一时间只允许一设备发送资料,若另一设备要发送资料,需等原来发送资料的设备发送完成后再处理。
- 全双工:全双工的系统允许二台设备间同时进行双向资料传输。
TCP 协议支持全双工
虽然目前使用最广泛的 HTTP1.1 基于 TCP 协议,但是它规定同一时间内客户端和服务器只能有一方主动发送数据。
这是因为 HTTP 在设计之初,考虑的是在网页中浏览文本的场景,能做到客户端发起请求、服务器进行响应即可。它并未考虑网页游戏这种,客户端和服务器之间需要相互主动发送大量数据的场景。为了更好地支持这样的场景,我们需要一个基于 TCP 的新协议 —— WebSocket 协议。
注意:Socket 和 WebSocket 的区别就像是雷锋和雷峰塔的区别。
2.2 建立 WebSocket 连接
在浏览网页时,我们一会儿使用 HTTP 协议看图文,一会儿使用 WebSocket 协议打游戏,一会儿刷视频。为了兼容这些应用场景,要求客户端和服务器在 TCP 三次握手建立起连接后,都统一使用 HTTP 请求先进行一次通信。如下图所示:
如果该请求是普通的 HTTP 请求,那么双方继续使用 HTTP 协议进行交互。如果该请求是建立 WebSocket 的请求,那么请求里会带上一些特殊的头部信息:
Connection: Upgrade # 客户端想升级协议
Upgrade: WebSocket # 客户端想升级成WebSocket协议
Sec-WebSocket-Key: T2a6wZlAwhgQNqruZ2YUyg # 用于验证的BASE64码
服务器使用公开算法将客户端的 BASE64 码变成一段字符串,放在 HTTP 响应里:
HTTP/1.1 101 Switching Protocols # 101协议切换状态码
Sec-WebSocket-Accept: iBJKv/ALlW2DobfoA4dmr3JHBCY= # 字符串
Upgrade: WebSocket
Connection: Upgrade
客户端也使用相同的公开算法将 BASE64 码变成一段字符串,如果和服务器传回来的字符串一致,那么验证通过。
WebSocket 协议(ws 协议)和 HTTP 协议都是基于 TCP 协议。在完成 TCP 三次握手之后,可以利用 HTTP 请求将 HTTP 协议升级为 ws 协议,后续双方使用 ws 协议的数据格式进行通信。如下图所示:
2.3 WebSocket 帧
在 ws 协议中,数据包被称为帧:
- opcode 用于指明帧的数据类型,=1 是指 text 类型,=2 是指二进制类型
- payload 用于指明所传输的数据的长度,单位是字节
3 WebSocket 解决的问题
这一小节相当于是总结了前文各种解决方案的优缺点。
3.1 HTTP 存在的问题
- HTTP 协议是一种无状态协议,其特性决定了在每次会话结束后,服务器端无法识别下一次发起请求的客户端身份。因此,为了确保通信的准确性,每次通信都必须重新确认对方身份,对实时通讯造成了障碍。
- HTTP 协议的通信遵循一次请求对应一次响应的模式。每次请求和响应都携带了大量的头部信息,这对于实时通讯而言,解析这些头部信息无疑增加了处理时间,从而降低了通信效率。
- HTTP 协议的通信机制是客户端主动发起请求,服务器被动响应。这种模式限制了服务器端的主动性,即服务器无法在没有客户端请求的情况下主动发送信息,从而无法实现实时通讯中的主动推送功能。
3.2 Ajax 轮询存在的问题
Ajax 轮询技术是指,客户端定期发起请求,以查询是否有新消息。若有新消息,则立即返回;若无,则等待预设的时间间隔后再次发起查询。该技术弥补了 HTTP 协议在实时更新方面的不足。
以一个具体场景为例:张三正在等待快递,由于他迫不及待,因此每隔 10 分钟就打电话给快递站询问快递是否到达。快递站无法主动通知张三,只有等到张三的电话才能告知他快递已到。
从上述例子中,我们可以看出两个问题:
- 假设张三的通话间隔为 10 分钟,在他收到快递前最后一次通话被告知尚未到达后,如果快递随即入库,那么张三在下一次通话时才能得知快递已到。这种通讯方式并不能算作实时通讯,因为可能存在 10 分钟的时间差。
- 假设张三所在的小区每天都有大量的快递需要接收,且每个人都采取主动致电的方式,那么快递站的电话占线也成为问题。
综上所述,Ajax 轮询技术存在的问题主要包括:
- 推送延迟:即使数据变更,服务器也只能在客户端发来请求时返回响应。
- 服务器压力:频繁的轮询会对服务器造成较大压力。
- 难以平衡推送延迟与服务器压力:减小轮询间隔虽能降低延迟,但会增加压力;增大轮询间隔虽能减轻压力,但会提高延迟。
3.3 长轮询存在的问题
针对上述 HTTP 协议在实时通讯方面的局限性,出现了一种解决方案 —— 长轮询技术。
长轮询技术是在 HTTP 协议的基础上,由客户端发起的一种特殊请求。在该机制中,如果服务器的数据没有发生变化,服务器将暂时挂起客户端的请求,直至数据更新或达到设定的超时时间才返回响应。如果超时,那么客户端会在收到响应后立即发起下一次长轮询请求。该技术克服了 HTTP 协议无法实现实时更新的缺陷,即一旦数据更新,服务器便迅速处理请求并返回响应。
在长轮询机制中,张三主动致电快递站并保持通话直至快递到达。如下图所示:
总体而言,长轮询技术存在以下优点:
- 没有推送延迟:服务器数据变更后,长轮询结束,能够迅速向客户端返回响应。
- 服务器压力小:长轮询的间隔通常较长,如 30 秒或 60 秒,且服务器在挂起连接期间并不会消耗过多的资源。
个人理解:虽然长轮询克服了定时轮询的诸多缺点,但是长轮询本质上还是需要客户端主动去发起请求,即需要张三亲自打电话去询问快递站,快递站是不会主动通知张三去取快递的。而 WebSocket 允许快递站通知张三,以帮助张三及时取到快递,因此它的实时性更好。
3.4 WebSocket 的改进
一旦 WebSocket 连接得以建立,后续的数据传输均采用帧序列的形式。在客户端主动断开 WebSocket 连接或服务器终止连接之前,双方无需重新发起连接请求。在处理大量并发连接及客户端与服务器之间交互频繁的场景下,此举显著降低了网络带宽资源的消耗,并展现出卓越的性能优势。客户端与服务器之间的消息发送与接收均在同一持久连接上进行,实现了真正的 “长连接”,其实时性优势尤为突出。
相关文章:

WebSocket 协议与 HTTP 协议、定时轮询技术、长轮询技术
目录 1 为什么需要 WebSocket?2 WebSocket2.1 采用 TCP 全双工2.2 建立 WebSocket 连接2.3 WebSocket 帧 3 WebSocket 解决的问题3.1 HTTP 存在的问题3.2 Ajax 轮询存在的问题3.3 长轮询存在的问题3.4 WebSocket 的改进 参考资料: 为什么有 h…...
二叉树节点问题
问题:设一棵二叉树中有3个叶子结点,有8个度为1的结点,则该二叉树中总的结点数为( 13)个 设某种二叉树有如下特点:每个结点要么是叶子结点,要么有2棵子树。假如一棵这样的二叉树中有m(m>0&…...

公司里的IT是什么?
公司里的IT是什么? 文章目录 公司里的IT是什么?1、公司里的IT2、IT技术3、IT行业4、IT行业常见证书 如果对你有帮助,就点赞收藏把!(。・ω・。)ノ♡ 前段时间,在公…...

【小程序爬虫入门实战】使用Python爬取易题库
文章目录 1. 写在前面2. 抓包分析 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研…...

案例 —— 怪物出水
一,Ocean Setup 设置海洋Surface Grid(使用Large Ocean工具架) 调节默认Grid的大小尺寸及细分(使用非常小尺寸来测试);调整频谱输入点的多少,频谱Grid Size,波浪方向,速度…...
vue中使用print.js实现页面打印并增加水印
1.安装print.js npm install print-js --save2.在main.js文件中引入并注册(我使用的是print.js的源码文件,并且做了一修改) //引入 import Print from ./utils/print//注册 Vue.use(Print); //注册3.在页面中使用 <template> <div class&quo…...

计算机基础(Windows 10+Office 2016)教程 —— 第5章 文档编辑软件Word 2016(下)
文档编辑软件Word 2016 5.4 Word 2016的表格应用5.4.1 创建表格5.4.2 编辑表格5.4.3 设置表格 5.5 Word 2016的图文混排5.5.1 文本框操作5.5.2 图片操作5.5.3 形状操作5.5.4 艺术字操作 5.6 Word 2016的页面格式设置5.6.1 设置纸张大小、页面方向和页边距5.6.2 设置页眉、页脚和…...

简单洗牌算法
🎉欢迎大家收看,请多多支持🌹 🥰关注小哇,和我一起成长🚀个人主页🚀 ⭐目前主更 专栏Java ⭐数据结构 ⭐已更专栏有C语言、计算机网络⭐ 在学习了ArrayList之后,我们可以通过写一个洗…...

JVM: 堆上的数据存储
文章目录 一、对象在堆中的内存布局1、对象在堆中的内存布局 - 标记字段2、JOL打印内存布局 二、元数据指针 一、对象在堆中的内存布局 对象在堆中的内存布局,指的是对象在堆中存放时的各个组成部分,主要分为以下几个部分: 1、对象在堆中的…...

AI产品经理的职责与能力:将AI技术转化为实际价值
一、AI产品经理的职责 发现和解决问题:AI产品经理需要具备敏锐的洞察力,能够发现用户需求和痛点,并提出相应的解决方案。传递价值给用户:AI产品经理需要确保产品能够满足用户的需求,提供价值,并提升用户体…...

【独家原创RIME-CNN-LSSVM】基于霜冰优化算法优化卷积神经网络(CNN)结合最小二乘向量机(LSSVM)的数据回归预测
【独家原创RIME-CNN-LSSVM】基于霜冰优化算法优化卷积神经网络(CNN)结合最小二乘向量机(LSSVM)的数据回归预测 目录 【独家原创RIME-CNN-LSSVM】基于霜冰优化算法优化卷积神经网络(CNN)结合最小二乘向量机(LSSVM)的数据回归预测效果一览基本介绍程序设计参考资料 效果一览 基本…...
如何对B站的热门视频进行分析
1. 视频内容分析 主题和类型:确定视频的主题和类型(如游戏、教育、生活、科技等),分析其是否符合当前流行趋势或特定兴趣群体。内容创意:评估视频内容的创意性和原创性,是否具有吸引力和独特性。内容质量&…...

MobaXterm tmux 配置妥当
一、事出有因 缘由:接上篇文章,用Docker搭建pwn环境后,用之前学过的多窗口tmux进行调试程序,但是鼠标滚动的效果不按预期上下翻屏。全网搜索很难找到有效解决办法,最后还是找到了一篇英文文章,解决了&…...

排序算法:快速排序,golang实现
目录 前言 快速排序 代码示例 1. 算法包 2. 快速排序代码 3. 模拟程序 4. 运行程序 5. 从大到小排序 快速排序的思想 快速排序的实现逻辑 1. 选择基准值 (Pivot) 2. 分区操作 (Partition) 3. 递归排序 循环次数测试 假如 10 条数据进行排序 假如 20 条数据进行…...

step:菜单栏静态加载和动态加载
文章目录 文章介绍静态加载动态加载补充材料 文章介绍 对比静态加载和动态加载。 主界面main.qml之前使用的是动态加载,动态加载导致的问题:菜单栏选择界面切换时,之前的界面内容被清空。 修改方法:将动态加载改为静态加载 左边是…...

【简历】武汉某985大学:前端简历指导,拿offer可能性低
注:为保证用户信息安全,姓名和学校等信息已经进行同层次变更,内容部分细节也进行了部分隐藏 简历说明 这是一份985武汉某大学25届的前端简历,那么985面向的肯定是大厂的层次,但是作为前端简历,学校部分&a…...
推荐系统的核心逻辑 MVP
我们将设计一个基于内容经济的推荐系统(Minimum Viable Product, MVP)。这个系统将通过收集用户行为数据,计算用户相似度,并生成个性化的推荐结果。推荐系统将包括数据收集、数据存储、数据处理和推荐服务几个关键部分。 MVP功能…...
Java中的BIO,NIO与操作系统IO模型的区分
Java中的IO模型 Java中的BIO,NIO,AIO概念可以是针对输入输出流,文件,和网络编程等其他IO操作的。 但是主要还是在网络编程通信过程中比较重要,因为很多情况网络编程需要它们来提供更好的性能。 所以本篇文章偏向于网络…...

AI砸掉了这些人的饭碗
在一般打工人眼里,金融圈往往被认为是高端脑力工作者的聚集地,他们工资高,学历高,能力强,轻易无法被替代。 可最近,偏偏一个“非人类”的物种,要来抢他们的饭碗。相关报道称,华尔街…...
端口及对应服务
端口是计算机网络中用于区分不同服务的逻辑概念。每个端口号都是一个16位的数字,其取值范围从0到65535。端口号被分为以下几类: 公认端口(Well-known ports):范围从0到1023,这些端口通常被分配给常见的服务…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...

C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...