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,这些端口通常被分配给常见的服务…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
