WebSocket 协议与 HTTP 协议、定时轮询技术、长轮询技术

news2024/11/15 17:02:33

目录

    • 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 连接或服务器终止连接之前,双方无需重新发起连接请求。在处理大量并发连接及客户端与服务器之间交互频繁的场景下,此举显著降低了网络带宽资源的消耗,并展现出卓越的性能优势。客户端与服务器之间的消息发送与接收均在同一持久连接上进行,实现了真正的 “长连接”,其实时性优势尤为突出。



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1966319.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode提示LeetCode extension needs Node.js installed in environment path

背景 系统:mac node版本 已通过nvm安装了多个版本node,并通过nvm alias default XX指定了node默认版本 描述:vscode安装了leetcode后,提示:LeetCode extension needs Node.js installed in environment path 问题…

leetcode958. 二叉树的完全性检验,层序遍历的巧用

leetcode958. 二叉树的完全性检验 给你一棵二叉树的根节点 root ,请你判断这棵树是否是一棵 完全二叉树 。 在一棵 完全二叉树 中,除了最后一层外,所有层都被完全填满,并且最后一层中的所有节点都尽可能靠左。最后一层&#xff0…

Web安全学习顺序:从零到精通的指南

随着互联网的迅猛发展,Web安全已成为一个日益重要的领域。无论是企业还是个人,都需要关注并提升自身的Web安全防护能力。对于初学者而言,如何系统地学习Web安全知识,掌握相关技能,成为了一个亟待解决的问题。本文将为你…

C# 串口通信(通过serialPort控件发送及接收数据)

连接串口 界面设计打开串口发送数据通过文件发送发送数据 接收数据 首先可以在 工具箱中搜索serialport,将控件拖到你的Winfrom窗口。 界面设计 打开串口 private void Connect_Click(object sender, EventArgs e){serialPort1.PortName comboBox2.Text;//端口名s…

颜色传感器 - 从零开始认识各种传感器【二十三期】

颜色传感器|从零开始认识各种传感器 1、什么是颜色传感器 颜色传感器(Color Sensor)是一种能够检测和识别颜色的传感器,它广泛应用于工业自动化、机器人技术、智能家居、消费电子等领域。颜色传感器通过测量物体表面反射的光来确定其颜色&a…

类和对象(上) - c++

1.类的定义 1.1 类定义格式 class 是定义类的关键字 ,后跟类的名字,{}部分为类的主体,(注意:最后类定义结束时不要忘了 ; )。 类体中内容称为类的成员:类中的变量称为成员变量; 类中的函数称为成员函数。在c中,struct也可以定义类(c兼容c语言),同时struct升级成类…

武汉流星汇聚:跨境电商桥梁连接中国与世界,中国产品畅销全球

在全球经济一体化的大背景下,零售电商行业以其独特的魅力和无限潜力,正引领着全球商业模式的深刻变革。特别是中国卖家,通过跨境电商平台这一桥梁,轻松触达全球消费者,实现了商品的快速流通和市场的广泛覆盖&#xff0…

Spark 基础 与 安装

Spark 基础 一、MapReduce编程模型的局限性 1、繁杂:只有Map和Reduce两个操作,复杂的逻辑需要大量的样板代码 2、处理效率低: Map中间结果写磁盘,Reduce写HDFS,多个Map通过HDFS交换数据 任务调度与启动开销大 3、…

十城联动共建生态登陆山东 纷享销客从原厂型向生态型CRM进化

7月30日,纷享销客渠道生态伙伴发展共建会之山东专场盛大举行,百余家优秀伙伴到场共享CRM领域高质量增长新机遇。2024年,纷享销客将坚定不移地从原厂型向生态型CRM厂商进化,把伙伴们扶上马,送一程,共发展&am…

Java--异常

目录 异常的概念异常的体系结构异常抛出异常处理异常throws声明try-catch捕获 异常处理流程自定义异常类 异常的概念 Java中,程序执行过程中发生的不正常的行为称为异常。 我们之前学数组的时候可能会遇到的数组越界异常:ArrayIndexOutOfBoundsException…

Reeder + RSS+ - 订阅RSS信息

文章目录 引言ReederRSS 源微博Bilibilirsshub自己发现 feed RSS 使用 引言 信息越来越多,也层次不齐,难以花时间筛选,但也不能闭目塞听。 使用爬虫 每日定时 去爬取不同网站需要的信息,还是有些繁琐,又让人想到 RSS …

odoo 去掉新手简介

很多模块有这样的提示,这种是可以动态关闭的 菜单 设置-技术-入职 可以动态切换,是否再次展示

不同类型的生物反应器在支架成熟过程中具有哪些特点和应用?

3D Bioprinting of Human Tissues: Biofabrication, Bioinks, and Bioreactors是发表于《International Journal of Molecular Sciences》的一篇综述,详细介绍了3D生物打印人体组织的相关技术进展,包括数据处理、生物打印技术、生物墨水配方、生物反应器…

设计理念中——抽象与接口和用(C#)

前言 在程序设计中,使用抽象类还是用接口应该是一个需要考虑的场景,有时我们感觉这两者并没有太大的区别,有时又有很大区别。这里是一些说明和示例。 一、抽象类和接口 1、相同点: 1)都可以被继承 2)都不能被实例化…

paddleSeg项目实战

问题1:cmake 编译报错 解决办法:添加一条语句 set(DEMO_NAME "test_seg") #这里的test_seg就是src里的文件名问题2: 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 LNK2038 检测到“RuntimeLibrary”的不匹配项: 值“MT_Stat…

汽车EDI中的常见术语以及流程详解

汽车EDI常见术语 EDI —— 电子数据交换3PL(第三方物流) —— 外包仓库/运输供应商。 一般用于售后市场,但偶尔也用于原始设备制造商。也可由原始设备制造商和售后市场公司用来分销产品。Aftermarket(后市场) —— 经…

详细阐述大模型微调过程、方法、案例

大模型微调 大模型微调(Fine-tuning)的定义是:在已经预训练好的大型深度学习模型基础上,使用新的、特定任务相关的数据集对模型进行进一步训练的过程。这种微调技术的主要目的是使模型能够适应新的、具体的任务或领域&#xff0c…

透明屏幕方案介绍

透明屏幕方案主要涉及透明显示屏的技术原理、应用场景、优势以及未来发展趋势等方面。以下是对透明屏幕方案的详细介绍: 一、技术原理 透明屏幕,特别是透明LED显示屏和透明OLED显示屏,采用了先进的技术原理来实现其独特的显示效果。 透明LED显…

牛客 KY11.二叉树遍历

牛客 KY11.二叉树遍历 思路: 我们接收字符串以后,创建一个二叉树结构体,然后就可以开始建立树,如果是字符就malloc新的结点去存储,是**#就返回空**,最后用递归以根左右的顺序创建结点。树建立完成后&#x…

Linux中防火墙实战之Web服务器和ssh远程服务配置指南

🏡作者主页:点击! 🐧Linux基础知识(初学):点击! 🐧Linux高级管理防护和群集专栏:点击! 🔐Linux中firewalld防火墙:点击! ⏰️创作…