为什么有了HTTP协议,还要有WebSocket协议?

文章目录

  • 使HTTP不断轮询
  • 长轮询
  • WebSocket是什么?
  • 怎么建立WebSocket连接
  • WebSocket抓包
  • WebSocket的消息格式
  • WebSocket的使用场景
  • 总结


平时我们打开网页,比如购物网站某宝。都是点一下列表商品,跳转一下网页就到了商品详情。

从HTTP协议的角度来看,就是点一下网页上的某个按钮,前端发一次HTTP请求,网站返回一次HTTP响应。

这种由客户端主动请求,服务器响应的方式也满足大部分网页的功能场景。

但有没有发现,这种情况下,服务器从来就不会主动给客户端发一次消息。

就像你喜欢的女生从来不会主动找你一样

但如果现在,你在刷网页的时候右下角突然弹出一个小广告,提示你【一个人在家偷偷才能玩哦】。

求知,好学,勤奋,这些刻在你DNA里的东西都动起来了。

你点开后发现。

长相平平无奇的古某提示你"道士9条狗,全服横着走"。

影帝某辉老师跟你说"系兄弟就来砍我"。

在这里插入图片描述

来都来了,你就选了个角色进到了游戏界面里。

在这里插入图片描述

这时候,上来就是一个小怪,从远处走来,然后疯狂拿木棒子抽你。

你全程没点任何一次鼠标。服务器就自动将怪物的移动数据和攻击数据源源不断发给你了。

这….太暖心了。

感动之余,问题就来了,像这种看起来服务器主动发消息给客户端的场景,是怎么做到的?

在真正回答这个问题之前,我们先来聊下一些相关的知识背景。

使HTTP不断轮询

其实问题的痛点在于,怎么样才能在用户不做任何操作的情况下,网页能收到消息并发生变更。

最常见的解决方案是,网页的前端代码里不断定时发HTTP请求到服务器,服务器收到请求后给客户端响应消息

这其实时一种伪服务器推的形式。

它其实并不是服务器主动发消息到客户端,而是客户端自己不断偷偷请求服务器,只是用户无感知而已。

用这种方式的场景也有很多,最常见的就是扫码登录

比如某信公众号平台,登录页面二维码出现之后,前端网页根本不知道用户扫没扫,于是不断去向后端服务器询问,看有没有人扫过这个码。而且是以大概1到2秒的间隔去不断发出请求,这样可以保证用户在扫码后能在1到2s内得到及时的反馈,不至于等太久。

在这里插入图片描述

但这样,会有两个比较明显的问题

  • 当你打开F12页面时,你会发现满屏的HTTP请求。虽然很小,但这其实也消耗带宽,同时也会增加下游服务器的负担。

  • 最坏情况下,用户在扫码后,需要等个1~2s,正好才触发下一次http请求,然后才跳转页面,用户会感到明显的卡顿。

在这里插入图片描述

那么问题又来了,有没有更好的解决方案?

有,而且实现起来成本还非常低。

长轮询

HTTP请求发出后,一般会给服务器留一定的时间做响应,比如3s,规定时间内没返回,就认为是超时。

如果我们的HTTP请求将超时设置的很大,比如30s,在这30s内只要服务器收到了扫码请求,就立马返回给客户端网页。如果超时,那就立马发起下一次请求。

这样就减少了HTTP请求的个数,并且由于大部分情况下,用户都会在某个30s的区间内做扫码操作,所以响应也是及时的。

在这里插入图片描述

比如,某度云网盘就是这么干的。所以你会发现一扫码,手机上点个确认,电脑端网页就秒跳转,体验很好。

在这里插入图片描述

真一举两得。

像这种发起一个请求,在较长时间内等待服务器响应的机制,就是所谓的长训轮机制。我们常用的消息队列RocketMQ中,消费者去取数据时,也用到了这种方式。

在这里插入图片描述

像这种,在用户不感知的情况下,服务器将数据推送给浏览器的技术,就是所谓的服务器推送技术,它还有个毫不沾边的英文名,comet技术,大家听过就好。

上面提到的两种解决方案,本质上,其实还是客户端主动去取数据。

对于像扫码登录这样的简单场景还能用用。

但如果是网页游戏呢,游戏一般会有大量的数据需要从服务器主动推送到客户端。

这就得说下websocket了。

WebSocket是什么?

我们知道TCP连接的两端,同一时间里,双方都可以主动向对方发送数据。这就是所谓的全双工。

现在使用最广泛的HTTP1.1,也是基于TCP协议的,同一时间里,客户端和服务器只能有一方主动发数据,这就是所谓的半双工。

也就是说,好好的全双工TCP,被HTTP用成了半双工。

为什么?

这是由于HTTP协议设计之初,考虑的是看看网页文本的场景,能做到客户端发起请求再由服务器响应,就够了,根本就没考虑网页游戏这种,客户端和服务器之间都要互相主动发大量数据的场景。

所以为了更好的支持这样的场景,我们需要另外一个基于TCP的新协议。

于是新的应用层协议websocket就被设计出来了。

大家别被这个名字给带偏了。虽然名字带了个socket,但其实socket和websocket之间,就跟雷峰和雷峰塔一样,二者接近毫无关系。

在这里插入图片描述

怎么建立WebSocket连接

我们平时刷网页,一般都是在浏览器上刷的,一会刷刷图文,这时候用的是HTTP协议,一会打开网页游戏,这时候就得切换成我们新介绍的websocket协议。

为了兼容这些使用场景。浏览器在TCP三次握手建立连接之后,都统一使用HTTP协议先进行一次通信。

  • 如果此时是普通的HTTP请求,那后续双方就还是老样子继续用普通HTTP协议进行交互,这点没啥疑问。

  • 如果这时候是想建立websocket连接,就会在HTTP请求里带上一些特殊的header头。

Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: T2a6wZlAwhgQNqruZ2YUyg==\r\n

这些header头的意思是,浏览器想升级协议(Connection: Upgrade),并且想升级成websocket协议(Upgrade: websocket)。

同时带上一段随机生成的base64码(Sec-WebSocket-Key),发给服务器。

如果服务器正好支持升级成websocket协议。就会走websocket握手流程,同时根据客户端生成的base64码,用某个公开的算法变成另一段字符串,放在HTTP响应的 Sec-WebSocket-Accept 头里,同时带上101状态码,发回给浏览器。

HTTP/1.1 101 Switching Protocols\r\n
Sec-WebSocket-Accept: iBJKv/ALIW2DobfoA4dmr3JHBCY=\r\n
Upgrade: websocket\r\n
Connection: Upgrade\r\n

http状态码=200(正常响应)的情况,大家见得多了。101确实不常见,它其实是指协议切换。

在这里插入图片描述

之后,浏览器也用同样的公开算法将base64码转成另一段字符串,如果这段字符串跟服务器传回来的字符串一致,那验证通过。

在这里插入图片描述

就这样经历了一来一回两次HTTP握手,websocket就建立完成了,后续双方就可以使用webscoket的数据格式进行通信了。

在这里插入图片描述

WebSocket抓包

我们可以用wireshark抓个包,实际看下数据包的情况。

在这里插入图片描述

上面这张图,注意画了红框的第2445行报文,是websocket的第一次握手,意思是发起了一次带有特殊Header的HTTP请求。

在这里插入图片描述

上面这个图里画了红框的4714行报文,就是服务器在得到第一次握手后,响应的第二次握手,可以看到这也是个HTTP类型的报文,返回的状态码是101。同时可以看到返回的报文header中也带有各种websocket相关的信息,比如Sec-WebSocket-Accept。

在这里插入图片描述

上面这张图就是全貌了,从截图上的注释可以看出,websocket和HTTP一样都是基于TCP的协议。经历了三次TCP握手之后,利用HTTP协议升级为websocket协议。

你在网上可能会看到一种说法:“websocket是基于HTTP的新协议”,其实这并不对,因为websocket只有在建立连接时才用到了HTTP,升级完成之后就跟HTTP没有任何关系了。

这就好像你喜欢的女生通过你要到了你大学室友的微信,然后他们自己就聊起来了。你能说这个女生是通过你去跟你室友沟通的吗?不能。你跟HTTP一样,都只是个工具人。

在这里插入图片描述

WebSocket的消息格式

上面提到在完成协议升级之后,两端就会用webscoket的数据格式进行通信。

数据包在websocket中被叫做帧。

我们来看下它的数据格式长什么样子。

在这里插入图片描述

这里面字段很多,但我们只需要关注下面这几个。

opcode字段:这个是用来标志这是个什么类型的数据帧。比如。

等于1时是指text类型(string)的数据包
等于2是二进制数据类型([]byte)的数据包
等于8是关闭连接的信号

payload字段:存放的是我们真正想要传输的数据的长度,单位是字节。比如你要发送的数据是字符串"111",那它的长度就是3。

在这里插入图片描述

WebSocket的使用场景

websocket完美继承了TCP协议的全双工能力,并且还贴心的提供了解决粘包的方案。它适用于需要服务器和客户端(浏览器)频繁交互的大部分场景。比如网页/小程序游戏,网页聊天室,以及一些类似飞书这样的网页协同办公软件

回到文章开头的问题,在使用websocket协议的网页游戏里,怪物移动以及攻击玩家的行为是服务器逻辑产生的,对玩家产生的伤害等数据,都需要由服务器主动发送给客户端,客户端获得数据后展示对应的效果。

在这里插入图片描述

总结

  • TCP协议本身是全双工的,但我们最常用的HTTP1.1,虽然是基于TCP的协议,但它是半双工的,对于大部分需要服务器主动推送数据到客户端的场景,都不太友好,因此我们需要使用支持全双工的websocket协议。

  • 在HTTP1.1里。只要客户端不问,服务端就不答。基于这样的特点,对于登录页面这样的简单场景,可以使用定时轮询或者长轮询的方式实现服务器推送(comet)的效果。

  • 对于客户端和服务端之间需要频繁交互的复杂场景,比如网页游戏,都可以考虑使用websocket协议。

  • websocket和socket几乎没有任何关系,只是叫法相似。

  • 正因为各个浏览器都支持HTTP协议,所以websocket会先利用HTTP协议加上一些特殊的header头进行握手升级操作,升级成功后就跟HTTP没有任何关系了,之后就用websocket的数据格式进行收发数据。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】编程题专项练习+答案

目录 1.删除有序数组中重复的数 2.用除二取余的方法,把任意一个十进制正数的二进制序列输出(不考虑溢出) 2.1如果是把任意一个十进制整数的二进制序列输出呢? 3.输出一个六行六列的整形矩阵,并输出其转置矩阵。矩阵…

C++之map

1、map介绍 map是C STL的一个关联容器,它提供一对一的数据处理能力。其中,各个键值对的键和值可以是任意数据类型,包括 C 基本数据类型(int、double 等)、使用结构体或类自定义的类型。 第一个可以称为关键字(key)&…

盘点国内大厂的10个AI创作工具,看看你都用过哪些?

国内大厂的 AI 创作工具,目前已经非常多了,而且有很多都是大家耳熟能详的。 下面整理了一些,包含 AI 绘画、AI 视频、AI 智能体、AI 大模型等多个方向的国内大厂 AI 创作工具。 发现有几款 AI 工具,还真的非常好用。看看这些 AI…

H5小游戏,斗地主

H5小游戏源码、JS开发网页小游戏开源源码大合集。无需运行环境,解压后浏览器直接打开。有需要的,私信本人,发演示地址,可以后再订阅,发源码,含60+小游戏源码。如五子棋、象棋、植物大战僵尸、开心消消乐、扑鱼达人、飞机大战等等 <!DOCTYPE html> <html> <…

算法46:动态规划专练(力扣198: 打家劫舍 力扣740:删除并获取点数)

打家劫舍问题&#xff1a; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定…

每日五道java面试题之mysql数据库篇(五)

目录&#xff1a; 第一题. 联合索引是什么&#xff1f;为什么需要注意联合索引中的顺序&#xff1f;第二题. 什么是数据库事务&#xff1f;第三题. 事物的四大特性(ACID)介绍一下?第四题. 按照锁的粒度分数据库锁有哪些&#xff1f;锁机制与InnoDB锁算法?第五题. 从锁的类别上…

Linux 防火墙 操作命令【实用】

防火墙操作&#xff1a; 描述命令查看防火墙状态systemctl status firewalld、firewall-cmd --state暂时关闭防火墙systemctl stop firewalld永久关闭防火墙systemctl disable firewalld开启防火墙systemctl start firewalld开放指定端口firewall-cmd --zonepublic --add-port…

Docker常见命令使用

Docker命令是使用Docker的基础。这里记录下Docker日常运维过程中经常使用到的一些命令&#xff0c;更全面的命令还请参考Docker官网。 docker用法概述 Docker命令可以通过CLI工具实现与服务器的交互。Docker命令的语法如下&#xff1a; docker [DOCKER-COMMAND] [OPTIONS] […

基于openKylin与RISC-V的MindSpore AI项目实践

项目目标&#xff1a; 在openKylin系统上安装和配置MindSpore框架。开发一个简单的图像分类模型&#xff0c;并在RISC-V平台上进行训练和推理。根据RISC-V的特性&#xff0c;对MindSpore框架进行必要的优化。 目录 项目目标&#xff1a; 训练模型 编写训练代码&#xff0c;设…

Mysql之存储过程与函数

Mysql之存储过程与函数 存储过程概述分类创建存储过程一般的语法格式完整的语法格式案例一案例二 调用存储过程调用语法格式 创建存储函数存储过程与函数的查看&#xff0c;修改和删除 存储过程概述 官网解释是&#xff1a;存储过程的英文是 Stored Procedure 。它的思想很简单…

微信小程序开发:循环定时删除阿里云oss上传的文件

上文有说到我们开发了定时删除阿里云oss的功能&#xff0c;但是一次只能删除10条。 本文我们做到一次删除全部过期的文件。 实现&#xff1a;使用while循环&#xff0c;在循环里获取是否还有已过期的&#xff0c;没有就break掉&#xff0c;有就走删除逻辑。 开始代码部分&am…

鸿蒙系统适配的流程

鸿蒙系统适配的流程通常涉及以下关键步骤&#xff0c;以下是鸿蒙系统适配的一般流程&#xff0c;具体流程可能会根据项目的具体需求和开发团队的情况进行调整和优化。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1. 准备工作&#…

常见限流算法及其实现

一、背景 在分布式系统中&#xff0c;随着业务量的增长&#xff0c;如何保护核心资源、防止系统过载、保证系统的稳定性成为了一个重要的问题。限流算法作为一种有效的流量控制手段&#xff0c;被广泛应用于各类系统中。本文将详细介绍四种常见的限流算法、两种常用的限流器工…

贝叶斯优化双向门控循环单元BO-BIGRU时序预测的matlab实现【源代码】

贝叶斯优化双向门控循环单元简介&#xff1a; 贝叶斯优化双向门控循环单元&#xff08;BO-BIGRU&#xff09;是一种结合了贝叶斯优化和双向门控循环单元&#xff08;BIGRU&#xff09;的神经网络模型。BIGRU是一种改进的循环神经网络&#xff08;RNN&#xff09;&#xff0c;它…

ArcGIS学习(十三)多源数据下的城市街道功能评估

ArcGIS学习(十三)多源数据下的城市街道功能评估 本任务带来的内容是多元数据下的城市街道功能评估。本任务包括两个关卡: 城市街道空间中观解读 城市街道功能详细评价 首先,我们来看看本任务的分析思路。 1.城市街道空间中观解读 下面我们正式进入第一关的内容一- 城市…

学习Python类型和对象,看这篇文章足矣!

类型与对象 一点基础理论: 对象代表现实世界中像轿车、狗、自行车这些事物。对象具有数据和行为两个主要特征。 在面向对象编程中&#xff0c;我们把数据当作属性&#xff0c;把行为当作方法。即&#xff1a; 数据 → 属性 和 行为 → 方法 类型是创造单个对象实例的蓝本。…

Vue基础入门(2)- Vue的生命周期、Vue的工程化开发和脚手架、Vue项目目录介绍和运行流程

Vue基础入门&#xff08;2&#xff09;- Vue的生命周期、Vue的工程化开发和脚手架、Vue项目目录介绍和运行流程 文章目录 Vue基础入门&#xff08;2&#xff09;- Vue的生命周期、Vue的工程化开发和脚手架、Vue项目目录介绍和运行流程5 生命周期5.1 Vue生命周期钩子5.2 在creat…

面向对象高级编程上

面向对象高级编程 一、面向对象高级编程上&#xff08;1&#xff09;C代码基本形式&#xff08;2&#xff09;Header中的防卫式声明&#xff08;3&#xff09;不带指针类的实现过程1. 防卫式声明2. 访问级别3.构造函数4.重载4.1 成员函数&#xff08;有this&#xff09;4.2 非成…

Igraph入门指南 1

Igraph入门指南 一、图的结构 图是顶点和边的集合&#xff0c;而边是通过顶点来描述。顶点和边&#xff0c;要用集合的理念去操作。 1、igraph中与图结构相关的函数 .igraph(), add_edges(), add_vertices(), complementer(),compose(), connect(), contract(), delete_ed…

自我对比: 通过不一致的解决视角更好地进行反思

一、写作动机&#xff1a; LLM 在自我评价时往往过于自信或随意性较大&#xff0c;提供的反馈固执或不一致&#xff0c;从而导致反思效果不佳。为了解决这个问题&#xff0c;作者提倡 "自我对比"&#xff1a; 它可以根据要求探索不同的解决角度&#xff0c;对比差异…