聊聊websocket那些事


前端必备工具推荐网站(免费图床、API和ChatAI等实用工具):
http://luckycola.com.cn/

一、什么是websocket?

WebSocket 是一种在单个 TCP 连接上进行全双工通信的网络协议。
它是 HTML5 中的一种新特性,能够实现 Web 应用程序和服务器之间的实时通信,比如在线聊天、游戏、数据可视化等。
相较于 HTTP 协议的请求-响应模式,使用 WebSocket 可以建立持久连接,允许服务器主动向客户端推送数据,避免了不必要的轮询请求,提高了实时性和效率。同时,WebSocket 的连接过程也比较简单,可以通过 JavaScript 中的 WebSocket API 进行创建和管理,并且可以和现有的 Web 技术如 HTML、CSS 和 JavaScript 无缝集成。
WebSocket 协议是基于握手协议(Handshake Protocol)的,它在建立连接时使用 HTTP/HTTPS 发送一个初始握手请求,然后服务器响应该请求,建立连接后就可以在连接上进行数据传输了。
在这里插入图片描述

二、websocket原理

在实现websocket连线过程中,需要通过浏览器发出websocket连线请求,然后服务器发出回应,这个过程通常称为“握手” 。
在 WebSocket API,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。在此WebSocket 协议中,为我们实现即时服务带来了两大好处:

1. Header:互相沟通的Header是很小的-大概只有 2 Bytes。
2. Server Push:服务器的推送,服务器不再被动的接收到浏览器的请求之后才返回数据,而是在有新数据时就主动推送给浏览器。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、websocket的特点和优势

1、特点:

1、WebSocket是一种在单个TCP连接上进行全双工通信的协议
2、WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据
3、在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

以前客户端想知道服务端的处理进度,要不停地使用 Ajax 进行轮询,让浏览器隔个几秒就向服务器发一次请求,这对服务器压力较高。另外一种轮询就是采用 long poll 的方式,这就跟打电话差不多,没收到消息就一直不挂电话,也就是说,客户端发起连接后,如果没消息,就一直不返回 Response 给客户端,连接阶段一直是阻塞的。
而 WebSocket 解决了 HTTP 的这几个难题。首先,当服务器完成协议升级后( HTTP -> WebSocket ),服务端可以主动推送信息给客户端,解决了轮询造成的同步延迟问题。由于 WebSocket 只需要一次 HTTP 握手,服务端就能一直与客户端保持通讯,直到关闭连接,这样就解决了服务器需要反复解析 HTTP 协议,减少了资源的开销。
在这里插入图片描述
在这里插入图片描述

WebSocket 是一种标准协议,用于在客户端和服务端之间进行双向数据传输。
但它跟 HTTP 没什么关系,它是一种基于 TCP 的一种独立实现。

2、优势:

在这里插入图片描述

3、劣势:

在这里插入图片描述

四、websocket与http异同点

1、异同点

在这里插入图片描述
在这里插入图片描述

2、心跳机制:

定义:为了保持NebSocket稳定的长连接,在连接建立之后,服务器和客户端之间通过心跳包来保持连接态,以防止连接因为长时间没有数据传输而被切断。
在这里插入图片描述

let WS = connectWS();
let heartbeatStatus = 'waiting';WS.addEventListener('open', () => {// 启动成功后开启心跳检测startHeartbeat()
})WS.addEventListener('message', (event) => {const { data } = event;console.log('心跳应答了,要把状态改为已收到应答', data);if (data === '"heartbeat"') {heartbeatStatus = 'received';}
})function startHeartbeat() {setTimeout(() => {// 将状态改为等待应答,并发送心跳包heartbeatStatus = 'waiting';WS.send('heartbeat');// 启动定时任务来检测刚才服务器有没有应答waitHeartbeat();}, 1500)
}function waitHeartbeat() {setTimeout(() => {console.log('检测服务器有没有应答过心跳包,当前状态', heartbeatStatus);if (heartbeatStatus === 'waiting') {// 心跳应答超时WS.close();} else {// 启动下一轮心跳检测startHeartbeat();}}, 1500)
}

五、websocket的兼容性

在这里插入图片描述

对于旧的浏览器该如何实现WebSocket的功能呢?下面就介绍一下几种常见的解决方案:

1. SockJS

SockJS是一个JavaScript库,它为浏览器提供了一个类似WebSocket的对象。
首先,它会优先使用原生的WebSocket;如果不支持,则使用streaming;如果streaming也不支持,则使用轮询(polling)。下面是支持的浏览器概览:
在这里插入图片描述

既然模拟WebSocket双向通信,那么使用SockJS时,也要配合使用相应的服务器端的库,下面可以使用的服务器端库:

  • SockJS-node
  • SockJS-erlang
  • SockJS-tornado
  • SockJS-twisted
  • SockJS-ruby
  • SockJS-netty
  • SockJS-gevent (SockJS-gevent fork)
  • SockJS-go

2、使用例子:

前端

1、首先加载SockJS库

<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>

2、初始化

var sock = new SockJS('https://mydomain.com/my_prefix');sock.onopen = function() {console.log('open');sock.send('test');};sock.onmessage = function(e) {console.log('message', e.data);sock.close();};sock.onclose = function() {console.log('close');};

后端-node

1、首先,安装sockjs-node:

npm install sockjs

2、初始化并且监听连接

var http = require('http');
var sockjs = require('sockjs');var echo = sockjs.createServer({ sockjs_url: 'http://cdn.jsdelivr.net/sockjs/1.0.1/sockjs.min.js' });
echo.on('connection', function(conn) {conn.on('data', function(message) {conn.write(message);});conn.on('close', function() {});
});var server = http.createServer();
echo.installHandlers(server, {prefix:'/echo'});
server.listen(9999, '0.0.0.0');

六、客户端服务端双向通信几种方式

客户端和服务端的通信方式有很多种,大多数场景下都是由客户端主动发送数据给服务端,但在特定的场景下(如多人协作、在线游戏)客户端还需要和服务端保持实时通信,此时需要使用双向通信。
常见的双向通信方式包括 HTTP 短轮询(polling)、HTTP 长轮询(long-polling)、XHR Streaming、Server-Sent Events、Websocket 等。

1、HTTP 短轮询

客户端每隔特定的时间(比如 1s)便向服务端发起请求,获取最新的资源信息。该方式会造成较多的资源浪费,尤其当服务端内容更新频率低于轮询间隔时,就会造成服务端资源、客户端资源的浪费。除此之外,过于频繁的请求也会给服务端造成额外的压力,当服务端负载较高的时候,甚至可能导致雪崩等情况发生。
在这里插入图片描述

2、HTTP 长轮询

解决了短轮询的一些问题,长轮询实现特点主要为当客户端向服务端发起请求后,服务端保持住连接,当数据更新响应之后才断开连接。然后客户端会重新建立连接,并继续等待新数据。此技术的主要问题在于,在重新连接过程中,页面上的数据可能会过时且不准确。
在这里插入图片描述

3、XHR Streaming

可以维护客户端和服务端之间的连接。但使用 XHR Streaming 过程中,XMLHttpRequest对象的数量将不断增长,因此在使用过程中需要定期关闭连接,来清除缓冲区。
在这里插入图片描述

iframe 流方式是在页面中插入一个隐藏的 iframe,利用其 src 属性在服务器和客户端之间创建一条长连接,服务器向 iframe 传输数据(通常是 HTML,内有负责插入信息的 java),来实时更新页面。

  • 优点:消息能够实时到达;浏览器兼容好
  • 缺点:服务器维护一个长连接会增加开销;IE、chrome、Firefox 会显示加载没有完成,图标会不停旋转。

4、WebSocket

它实现了浏览器与服务端全双工通信。前面我们提到,HTTP 短轮询、长轮询都会带来额外的资源浪费,因此 Websocket 在实现实时通信的同时,能更好地节省服务端资源和带宽。
Websocket 建立在 TCP 协议之上,握手阶段采用 HTTP 协议,但这个 HTTP 协议的请求头中,有以下的标识性内容。
Connection: Upgrade、Upgrade: websocket:表示这个连接将要被转换为 WebSocket 连接。
Sec-WebSocket-Key:向服务端提供所需的信息,以确认客户端有权请求升级到 WebSocket。
Sec-WebSocket-Protocol:指定一个或多个的 WebSocket 协议。
Sec-WebSocket-Version:指定 WebSocket 的协议版本。
如果服务端同意启动 WebSocket 连接,会在握手过程中的 HTTP 协议中返回包含Sec-WebSocket-Accept的响应消息,接下来客户端和服务端便建立 WebSocket 连接,并通过 WebSocket 协议传输数据。
在这里插入图片描述

在海量并发和客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息是在同一个持久连接上发起,实时性优势明显。
在这里插入图片描述

七、websocket的应用

扫码登录实现
在这里插入图片描述

八、ChatGPT即使通信-SSE

SSE(Server-Sent Events)是一种用于实现服务器主动向客户端推送数据的技术,也被称为“事件流”(Event Stream)。它基于 HTTP 协议,利用了其长连接特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端的实时数据推送。

1. 技术实现

SSE 基于 HTTP 协议,利用了其长连接特性,通过浏览器向服务器发送一个 HTTP 请求,建立一条持久化的连接。而 WebSocket 则是通过特殊的升级协议(HTTP/1.1 Upgrade 或者 HTTP/2)建立新的 TCP 连接,与传统 HTTP 连接不同。

2. 数据格式

SSE 可以传输文本和二进制格式的数据,但只支持单向数据流,即只能由服务器向客户端推送数据。WebSocket 支持双向数据流,客户端和服务器可以互相发送消息,并且没有消息大小限制。

适用于场景
chatGPT 返回的数据 就是使用的SSE 技术
实时数据大屏 如果只是需要展示 实时的数据可以使用SSE技术 而不是非要使用webSocket

前端调用

const sse = new EventSource('http://localhost:3000/api/sse' )sse.addEventListener('open', (e) => {console.log(e.target)
})
//对应后端nodejs自定义的事件名lol
sse.addEventListener('lol', (e) => {console.log(e.data)
})

nodejs 后端操作

import express from 'express';
const app = express();
app.get('/api/sse', (req, res) => {res.writeHead(200, {'Content-Type': 'text/event-stream', //核心返回数据流'Connection': 'close'})const data = fs.readFileSync('./index.txt', 'utf8')const total = data.length;let current = 0;//mock sse 数据let time = setInterval(() => {console.log(current, total)if (current >= total) {console.log('end')clearInterval(time)return}//返回自定义事件名res.write(`event:lol\n`)/返回数据res.write(`data:${data.split('')[current]}\n\n`)current++}, 300)
})
app.listen(3000, () => {console.log('Listening on port 3000');
});

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

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

相关文章

大量的视频如何批量随机分割的方法:批量剪辑不求人

在处理大量视频文件时&#xff0c;经常要进行随机分割&#xff0c;满足不同的需求。制作短视频、片段集锦等&#xff0c;批量随机分割视频都是一个高效的方法。下面来看云炫AI智剪如何操作的吧。 分割后的视频缩略图展示&#xff0c;被分割的视频自动分类保存在对应的文件夹中。…

Editplus配置Java运行环境

目录 找工具&#xff08;图1&#xff09; 编译Java&#xff1a;-d classes是在文件classes编译&#xff08;图2&#xff09; 运行Java&#xff1a;-classpath classes是在文件classes运行&#xff08;图3&#xff09; 编译和运行Java &#xff08;图4-5&#xff09; 找工具…

张载为往圣继绝学,唯一的错是不够强大

“自古雄才多磨难&#xff0c;从来纨绔少伟男。” 张载&#xff0c;人称“横渠先生”。他在横渠镇&#xff0c;授徒讲学&#xff0c;恢复古礼&#xff0c;试验井田&#xff0c;写书《正蒙》。张载讲学关中&#xff0c;弟子多为关中人&#xff0c;其学派被称作关学。 张载自学…

YOLOv5源码中的参数超详细解析(7)— yolo.py

前言:Hello大家好,我是小哥谈。YOLOv5是一种先进的目标检测算法,它可以实现快速和准确的目标检测。yolo.py是YOLOv5项目中的一个Python文件,用于实现目标检测算法。该文件包含了YOLOv5模型的定义、训练和推理过程。本节课就结合源码对yolo.py文件进行逐行解析~!🌈 前期…

C++I/O流——(4)文件输入/输出(第一节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

8 - MySQL数据读写分离|MySQL多实例

MySQL数据读写分离&#xff5c;MySQL多实例 MySQL数据读写分离数据读写分离如何实现数据的读写分离提供数据读写分离服务的软件&#xff08;中间件&#xff09;maxscale 软件提供的读写分离服务的工作过程配置数据读写分离结构 提供数据存储服务 MySQL多实例 MySQL数据读写分离…

二分-补题

文章目录 造海船描述输入描述输出描述样例输入 1样例输出 1提示题解 寻找第一个1题目描述输入描述输出描述测试用例题解 查找数字是否出现描述输入描述输出描述样例输入 1样例输出 1题解 字典找数描述输入描述输出描述样例输入 1样例输出 1题解 寻找第一个偶数题目描述输入描述…

安全兜底:涉及钱时短信必须考虑防刷、限量和防重

开放平台资源的使用需要考虑防刷 短信验证码服务属于开放性服务&#xff0c;由用户侧触发&#xff0c;且因为是注册验证码所以不需要登录就可以使用,很容易被短信轰炸平台利用 GetMapping("wrong") public void wrong() {sendSMSCaptcha("13600000000");…

ubuntu卸载docker

简介&#xff1a;docker虽然好用&#xff0c;但是存在着以下几个问题&#xff1a; 1、空间占用过大&#xff0c;Docker在本地存储映像文件和容器&#xff0c;如果没有及时清理会占用大量磁盘空间。 2、安全性问题&#xff1a;虽然Docker提供了一些安全机制&#xff0c;但仍有…

关于 setData 同步异步的问题

小程序官方文档中的回答解释: 所以大概意思就是: 1.setData在逻辑层的操作是同步&#xff0c;因此this.data中的相关数据会立即更新,比如下面的例子: const a 1 this.setData({b: a ? a : , }) console.log(that.data.b) // 1 2. setData在视图层的操作是异步&#xff0c;…

自定义白平衡调节的步骤 白平衡怎么设置好 白平衡和色温的关系 用什么软件调节白平衡

不管是拍摄视频/图片&#xff0c;还是视频/图片后期处理&#xff0c;白平衡调节都是很重要的环节&#xff0c;比如在氛围感很好咖啡厅内拍一张照&#xff0c;但是拍出来的人物脸色蜡黄&#xff0c;就是因为白平衡没设置好&#xff0c;下面就说说自定义白平衡调节的步骤&#xf…

力扣labuladong——一刷day92

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣211. 添加与搜索单词 - 数据结构设计二、力扣677. 键值映射 前言 Trie 树又叫字典树、前缀树、单词查找树&#xff0c;是一种二叉树衍生出来的高级数据…

java: 5-6 break

文章目录 1. break1.1 介绍1.2 语法和流程图1.3 入门练习1.4 细节说明1.5 练习 【老韩视频p137-】 1. break 看个需求&#xff1a;随机生成 1-100 的一个数&#xff0c;直到生成了 97 这个数&#xff0c;看看你一共用了几次? 【思路分析:循环&#xff0c;但是循环的次数不知道…

C++ | 三、字符串string、引用、函数

&#xff08;以下内容对应卡码网题目10.平均绩点、11.句子缩写&#xff09; 字符串string类型 相较于用单引号括起来的字符char类型&#xff0c;用双引号""括起来的字符串string类&#xff08;这是C标准库中定义的一个类&#xff09;可表示多个字符&#xff0c;并支…

大厂咋做支付系统的核对?

核对是保障资金安全的重要机制。 时效角度&#xff0c;主要有&#xff1a; &#xff08;准&#xff09;实时核对 准确性不如离线核对&#xff0c;且需相应实时核对平台建设 离线核对&#xff08;如 T1 核对&#xff09; 主要问题是发现问题的时机较为后置&#xff0c;部分场景…

OD机考真题搜集:考古学家

题目 有一个考古学家发现一个石碑,但是很可惜,发现时其已经断成多段,原地发现n个断口整齐的石碑碎片。为了破解石碑内容,考古学家希望有程序能帮忙计算复原后的石碑文字组合数,你能帮忙吗? 输入 第一行输入n,n表示石碑碎片的个数。 第二行依次输入石碑碎片上的文字内…

初学者的嵌入式 Linux 计划!

俗话说万事开头难&#xff0c;刚开始的时候&#xff0c;是不是根本就不知如何开始&#xff1f;今天给大家分享一个嵌入式大神总结的Linux学习计划&#xff01;希望给大家提供帮助&#xff0c;&#xff1b;另外想要系统学习也可以dd我&#xff01; 第一阶段&#xff1a;嵌入式硬…

Java基础之并发篇(二)

1、前言 本篇主要基于Java基础之并发篇&#xff08;一&#xff09;继续梳理java中关于并发相关的基础只是。本篇基于网络整理&#xff0c;和自己编辑。在不断的完善补充哦。 2、synchronized 的原理是什么? synchronized是 Java 内置的关键字&#xff0c;它提供了一种独占的…

【复现】大华 DSS 数字监控系统 SQL 注入漏洞_18

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 大华DSS是大华的大型监控管理应用平台&#xff0c;支持几乎所有涉及监控等方面的操作&#xff0c;支持多级跨平台联网等操作。 可…

Echarts图表如何利用formatter自定义tooltip的内容和样式

在展示多数据图表的时候 有的时候需要图例也展示出一些内容来&#xff0c;例如官方这样子&#xff1a;鼠标悬停的时候展示该点数据 但是&#xff0c;官方提供的样式有时不适用所有的开发场景 我的项目需要实现鼠标悬停在某一点的时候&#xff0c;只展示该条线的数据&#xff0…