为什么会有websocket(由来)

一、HTTP 协议的缺点和解决方案

1、HTTP 协议的缺点和解决方案

用户在使用淘宝、京东这样的网站的时候,每当点击一个按钮其实就是发送一个http请求。那我们先来回顾一下http请求的请求方式。
在这里插入图片描述
一个完整的http请求是被分为request请求节点和response响应阶段的,而且从来都是客户端给服务器端发送http请求,从来没有服务器端主动给我们发送请求。
但是有的时候我们在玩一些单机游戏的时候,游戏上的人物总是能将供给数据发送给我们,那么像是这种服务器主动给浏览器不断发送数据的场景是怎么实现的呢?

2.如何实现服务器主动发数据

①:HTTP定时轮询

定时轮询是一种很常见的处理方案,就是客户端不断的发送http请求到服务器当中,服务器收到请求后响应消息,这是一种伪服务器推的方式,他其实不是服务器主动发送消息到客户端,而是客户端不断偷偷请求服务器,只是用户无感知而已!
在这里插入图片描述
使用这种常见的方式有很多,最常见的就是扫码登录。比如微信登录。当我们打开扫码页面以后,前端页面根本就不知道用户扫没扫码,于是不断的向服务器后端进行询问,询问的间隔是1-2s这样可以保证用户在扫码后,能在1-2s内得到及时的反馈!
在这里插入图片描述
这用作存在的问题
第一:当我们打开f12的时候,满屏都是http请求,虽然每个请求都很小,但是这么多的数量也会消耗很多带宽,同时也会加重服务器的负担。
第二:及时是最快的情况下,用户扫码完成后,同样需要等到1-2s,等到下一次http请求,才能从服务器当中将数据读取出来返回给用户,这样会给用户明显的卡段感。

②:HTTP长轮询机制

我们知道http请求一般会给服务器一定的时间去处理请求,然后返回数据。如果在这一段时间内浏览器没有接收到服务器的响应,那么浏览器就认为该http请求超时,浏览器会进行重传。
在这里插入图片描述
但是如果我们将http请求的超时设置的很大,比如30s,在这30s内只要服务器接受到了扫码请求,就立马返回给前端网页数据。
如果超时那就立马发起下一次请求,这样就减少了http请求的个数。并且大多数情况下用户都会在某个30秒的时间内,做出扫码操作,所以此时响应就会非常及时。
比如百度云网盘就是这样做的,所以我们扫码,在手机上点击确认,浏览器会马上变成登录状态。用户体验很好。
向这样发起一个请求在较长时间内等待服务器响应的机制就是长轮训机制。我们常用的消息队列rocketMQ消费者取数据就是就是长轮询机制!
向这样在用户不感知的情况下服务器将数据推送给浏览器的技术就是服务器推送技术,它还有一个毫不沾边的英文名称—comet技术
以上提到的两种解决方案本质上还是客户端主动从服务器端取数据,对于扫码登录这样的简单场景还能用用,但是如果是网页游戏,游戏一般会有大量的数据会从服务器端推送到客户端,那么如何实现呢?

二、websocket的由来

我们首先要了解计算机网络当中的TCP/IP协议栈,下层协议要为上层协议提供基础。
在这里插入图片描述
TCP协议属于传输层的协议,它是一种全双工协议。
在这里插入图片描述
而http协议的访问流程是客户端浏览器给服务器发送数据,然后服务器处理后给浏览器返回响应,这是妥妥的半双工协议。
也就意味着好好的全双工协议到了http就右给干回了半双工!
这主要是因为在http协议的设置之初,主要考虑的是查看网页文本的场景,能够做到客户端发送请求,再由服务器响应就够了,根本就没想到网页游戏这种客户端和服务器端相互主动发送大量数据的场景,所以为了更好的去应对这种场景,我们需要一个基于TCP的新协议,于是新的网络层协议websocket就被设计出来了。
注意:websocket和socket之间就像雷锋和雷峰塔一样毫无关系,别被名字带偏。

三、如何建立websocket链接

我们在浏览器上经常是一会儿刷刷图文、一会儿打会儿游戏。刷图文就是使用的websocket协议,而打游戏就要使用websocket协议。为了兼容这些使用场景浏览器在TCP三次握手以后都使用http协议进行一次通讯。
在这里插入图片描述
如果此时客户端发起的是普通的http请求,那后续双方就还是老样子,继续用股通HTTP协议进行交互,这点没啥疑问。果这时候是想建立websocket链接,就需要在http请求的请求头header带上特殊的信息。
包含:

  • Connection: Upgrade // 标识该HTTP请求是一个协议升级请求
  • Upgrade: websocket //协议升级为WebSocket协议
  • Sec-sebSocket-Key: dGhlIHNhbx8sZSBub25SjZQ== //随机生成的Base64码
GET ws://localhost/chat HTTP/1.1  //请求协议为 ws
Host: localhost
Upgrade: websocket  //协议升级为WebSocket协议
Connection: Upgrade  // 标识该HTTP请求是一个协议升级请求
Sec-sebSocket-Key: dGhlIHNhbx8sZSBub25SjZQ==  //客户端采用base64编码的24为随机字符序列,服务器//接受客户端HTTP协议升级的证明,要求服务器响应一个//对应加密的Sec-webSocket-Accept头信息作为应答
Sec-webSocket-Extensions: permessage-dflate  //协议扩展类型
Sec-webSocket-Version: 13  //客户端支持WebSocket协议版本

将以上信息返送给服务器以后,如果服务器可是升级为websocket协议,就会走websocket握手流程。同时将客户端给到的Base64码用公开算法变成另一段字符串。放在http的响应头当中的Sec-webSocket-Accept。同时在带上101状态码返回给客户端。101状态码确实不常见,它其实是指协议切换。
在这里插入图片描述

HTTP/1.1 101 Switching Protocols  //服务器响应101代码说明握手成功
Upgrade: websocket
Connection: Upgrade
Sec-webSocket-Accept: s3pPLMBiTxaQ9kyGzzhZRbk+XOo=
Sec-webSocket-Extensions: permesssage-deflate

浏览器得到响应的数据以后也会使用同样的公开算法,将发送给服务器的Base64码也转换成字符串。如果这段字符串和公开传回来的字符串一致,那么就验证通过。
在这里插入图片描述
websocket和http一样都是应用层协议,他们也都是基于TCP的协议。ws协议的流程是:
1.首先经过TCP的三次握手
2.利用http协议升级为ws协议
3.后续双方通过websocket数据格式进行通信

在这里插入图片描述

四、websocket的实现方式

  • 后端实现方式:
    • 编程式:即继承类javax.websocket.Endpoint并实现其方法。
    • 注解式:即定义一个 POJO, 并添加@ServerEndpoint相关注解。
  • 前端实现方式:
    • 使用 html5 原生的 api。
    • 使用 socktjs/stompjs 框架提供的 api。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot项目部署到linux服务器

springboot后端 修改前 修改后 vue前端 修改前 将地址中的 localhost改为 ip 重新生成war包 war上传到linux的tomcat的webapps下 其他环境配置和macOS大差不差 Tomcat安装使用与部署Web项目的三种方法_tomcat部署web项目-CSDN博客

go升级后 编译的exe在win7上无法正常运行

D:/Go/src/runtime/sys_windows_amd64.s:65 x75 fpx22fca sp-0x22fc8日 升级到go 1.21后报一堆错误,要死了啊 原来是go 1.21不支持win7了,必须把go退回到1.20版本 谷歌发布编程语言 Go 1.21 版本:取消支持微软 Win7/8 及苹果 macOS 10.13/10…

linux安装mysql后,配置mysql,并连接navicate软件

Xshell连接登陆服务器 输入全局命令 mysql -u root -p 回车后,输入密码,不显示输入的密码 注意mysql服务状态,是否运行等 修改配置文件my.cnf,这里没找到就找my.ini,指定有一个是对的 find / -name my.cnf 接下…

MySQL数据库案例实战教程:数据类型、语法与高级查询详解

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

Flink 通过 paimon 关联维表,内存降为原来的1/4

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…

Windows UWP ContentDialog去掉阴影(全透明)的实现

一、前言 在WIndows开发中,使用UWP(Universal WIndows)项目开发过程中,使用ContentDialog 的过程中,我们可能并不满足现有的样式,这时就需要自定义样式。笔者在自定义样式过程中,遇到了一个难题…

18 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 地表水储量变化Glads水文数据处理

18 - grace数据处理 - 补充 - 地下水储量计算过程分解 - 地表水储量变化 0 引言1 Grace陆地水储量过程整合0 引言 由水量平衡方程可以将地下水储量的计算过程分解为3个部分,第一部分计算陆地水储量变化、第二部分计算地表水储量变化、第三部分计算地下水储量变化。本篇简单介绍…

Android 逆向学习【1】——版本/体系结构/代码学习

#Android 历史版本 参考链接:一篇文章让你了解Android各个版本的历程 - 知乎 (zhihu.com) 三个部分:api等级、版本号、代号(这三个东西都是指的同一个系统) API等级:在APP开发的时候写在清单列表里面的 版本号&…

【Python-OS】os.path.splitext()

作用:将文件路径分割成文件名和扩展名两部分。 slide_id, _ os.path.splitext(slide) print("slide:") print(slide) print("slide_id:") print(slide_id)注: slide是文件名,可以自行赋值

【Go语言入门学习笔记】Part3.指针和运算符、以及基本输入

一、前言 仍然好多和C语言类似,计算机的学生应该是很容易入门这一环节,我还在最后的输入中看到了一些些Java输入的影子,而自动的变量类型推断更是有Python那个味道,正可谓几百家之所长了。 二、学习代码 package mainimport (&q…

Angular(1):使用Angular CLI创建空项目

要创建一个空的 Angular 项目,可以使用 Angular CLI(命令行界面)。以下是使用 Angular CLI 创建一个新项目的步骤: 1、安装 Angular CLI: 打开你的命令行界面(在 Windows 上是 CMD、PowerShell 或 Git Bas…

动态内存管理—C语言通讯录

目录 一,动态内存函数的介绍 1.1 malloc和free 1.2 calloc 1.3 realloc 1.4C/C程序的内存开辟 二,通讯录管理系统 动态内存函数的介绍 malloc free calloc realloc 一,动态内存函数的介绍 1.1 malloc和free void* malloc (…

mysql实战——Mysql8.0高可用之双主+keepalived

一、介绍 利用keepalived实现Mysql数据库的高可用,KeepalivedMysql双主来实现MYSQL-HA,两台Mysql数据库的数据保持完全一致,实现方法是两台Mysql互为主从关系,通过keepalived配置VIP,实现当其中的一台Mysql数据库宕机…

Vite + Vue3 + Electron 创建打包桌面程序

10 【Vite Vue3 Electron 创建打包桌面程序】 1.使用 Vite 构建 Electron 项目 1.1 创建 Vite 应用,安装 Electron 依赖 创建一个 Vite 项目 npm init vitelatest安装 Electron 相关依赖 npm install electron -D npm install vite-plugin-electron -D 1.2 在…

拉格朗日插值及牛顿差商方法的实现(Matlab)

一、问题描述 拉格朗日插值及牛顿差商方法的实现。 二、实验目的 掌握拉格朗日插值和牛顿差商方法的原理,能够编写代码实现两种方法;能够分析多项式插值中的误差。 三、实验内容及要求 利用拉格朗日插值及牛顿差商方法估计1980 年的人口,并…

FreeRTOS_信号量_学习笔记

信号量的特性 消息队列用于传输多个数据,但是有时候我们只需要传递状态,这个状态值需要用一个数值表示。套用队列笔记中的流水线例子,可以理解为流水线上工件的数量。 信号:起通知作用 量:还可以用来表示资源的数量 当…

场景文本检测识别学习 day10(MMdetection)

配置文件(config) 由于在大型项目中,一种模型需要分:tiny、small、big等很多种,而它们的区别主要在网络结构,数据的加载,训练策略等,且差别很多都很小,所以如果每个模型都手动从头写一份&#…

三十、openlayers官网示例解析Double click, Drag and Zoom——第二次点击鼠标拖拽缩放地图效果、取消地图双击放大事件

这篇展示了如何在地图上添加第二次按下鼠标移动鼠标实现拖拽缩放地图效果。 官网demo地址: Double click, Drag and Zoom 官网介绍文字的翻译如下: 示例比较简单,直接贴代码: const map new Map({//添加第二次点击拖拽缩放地图i…

【Postman接口测试】第二节.Postman界面功能介绍(上)

文章目录 前言一、Postman前言介绍二、Postman界面导航说明三、使用Postman发送第一个请求四、Postman 基础功能介绍 4.1 常见类型的接口请求 4.1.1 查询参数的接口请求 4.1.2 表单类型的接口请求 4.1.3 上传文件的表单请求 4.1.4 JSON 类…

vue 展示svg矢量图可缩放拖动

使用插件&#xff1a;svg-pan-zoom <template> <!-- svg图--><div id"svgContainer"></div> </template><script> import svgPanZoom from svg-pan-zoom import svgFile from ../datav/img/220kVscb.svg // 路径根据实际情况调…