【WebSocket】前端使用WebSocket实时通信

目录

  • 前言
  • 什么是WebSocket
  • WebSocket的工作原理
  • WebSocket与HTTP的关系
  • HTTP建立持久化连接
  • WebSocket类封装

前言

最近写项目,需要实现消息通知和实时聊天的功能,就去了解了一些关于websocket的知识,总结如下。

什么是WebSocket

WebSocket 是一种在 Web 应用中实现实时通信的协议。与传统的 HTTP 请求不同,WebSocket 连接在客户端和服务器之间建立一个持久性双向通信管道,使得数据可以在连接打开后随时传递。这消除了 HTTP 请求的开销,能更好的节省服务器资源和带宽,同时在实时应用中提供了更好的性能和响应性。

WebSocket 就像是你和服务器之间的一个电话线,可以在任何时候进行通话。和普通的浏览网页不同,WebSocket 让你能够实时地接收和发送信息,而不需要频繁地向服务器询问是否有新的消息。

WebSocket的工作原理

WebSocket 协议的工作原理基于握手(handshake)和消息传递。当客户端发起 WebSocket 握手请求时,服务器将进行握手确认,建立连接。一旦连接建立,客户端和服务器可以互相发送消息,而不必每次都进行新的握手。

  1. 建立连接: 在客户端(浏览器)发起 WebSocket 连接请求时,服务器会进行响应,建立一个持久的连接通道。这个过程类似于握手,它使用了 HTTP/HTTPS 协议来发起连接请求。
  2. 双向通信: 连接建立成功,客户端和服务器都可以通过这个通道实时地发送和接收数据,消息可以是文本或二进制数据。不像传统的 HTTP 请求,WebSocket 允许服务器主动向客户端推送数据,也允许客户端向服务器发送请求,实现双向通信。
  3. 保持连接: 一旦连接建立,客户端和服务器之间就会保持一个持久的连接通道,不需要每次都重新建立连接。这使得数据传输更加高效,减少了不必要的连接建立和关闭开销。
  4. 关闭连接: 当客户端或服务器希望终止连接时,可以发送一个特殊的关闭帧,告知对方要关闭连接。对方接收到关闭帧后,也会发送一个确认帧,并关闭连接。这是一个优雅的断开连接方式,不需要像传统的 HTTP 请求那样等待服务器的响应。类似于双方结束通话,然后挂断电话。

WebSocket与HTTP的关系

WebSocket 和 HTTP 是两种不同的协议,它们有着不同的通信方式、连接状态和数据传输方式。WebSocket在实现实时性通信方面更加高效,而 HTTP 更适用于请求-响应式的短期数据交换。

  • 共同点: WebSocket 和 HTTP 都是用于网络通信的协议,都是在应用层工作。它们都基于 TCP/IP 协议,用于在客户端和服务器之间传输数据。
  • 联系: WebSocket 协议最初是作为 HTTP 协议的扩展而提出的,因此在握手阶段使用了 HTTP 协议来建立连接。WebSocket 握手请求使用的是 HTTP 请求,然后在协议升级时切换到 WebSocket 协议,建立持久的双向连接。所以,WebSocket是在 HTTP 协议的基础上构建的。
  • 区别:
    1. HTTP是请求-响应式通信,数据通常单向传输。而WebSocket 是全双工通信,双向数据传输。
    2. 在 HTTP 中,每次请求和响应都会携带大量的头部信息,这些信息描述了请求和响应的性质。而在 WebSocket 握手时,也会有一些头部信息,但之后数据传输时的头部相对较少,从而减少了传输开销,且websocket没有像http那样可以只定义请求头的一些参数,只有一个Sec-WebSocket-Protocol属性用于自定义子协议。
    3. HTTP 适用于传输短期请求-响应式的数据,如网页的加载和表单提交。WebSocket 更适用于实时性要求较高的场景,如在线聊天、实时数据更新、多人协作等。

HTTP建立持久化连接

HTTP Keep-Alive (长连接): 长连接是一种保持连接打开的通信方式,客户端与服务器建立连接后,在一段时间内保持连接处于打开状态,以便后续的 HTTP 请求复用它。在长连接中,一次 TCP 连接可以被用来发送多个 HTTP 请求和响应,而不是每次请求都建立一个新的连接。

Keep-Alive 适用于需要实时数据传输的场景,如聊天应用、实时游戏、实时数据监控等。它可以实现低延迟的实时通信,提高通信效率。但需要维护长时间的连接状态,对服务器资源和网络负载有一定影响。

Long Polling(长轮询) :长轮询是一种模拟实时通信的方法。在长轮询中,客户端发送一个请求到服务器,服务器在等待新数据或事件的时候,保持连接打开,直到有新的数据或事件发生时才发送响应给客户端。客户端收到响应后立即处理,然后再次发送请求,以保持连接。

长轮询适用于不支持真正长连接的环境,如基于HTTP协议的环境。它可以模拟实时通信,但因为每次响应后都需要重新建立连接,所以在一些情况下可能会有较高的延迟和网络开销。

WebSocket类封装

class WebSocketClass {constructor(wsurl, time) {this.wsurl = wsurl //连接地址this.token = localStorage.getItem("accessToken")this.time = time //多少秒执行检测this.socketTask = nullthis.is_open_socket = false //避免重复连接this.heartbeatInterval = null //检测服务器端是否还活着this.reconnectTimeOut = null //重连之后多久再次重连this.connectSocketInit()}// 建立初始连接connectSocketInit() {this.socketTask = new WebSocket(this.wsurl, this.token)// 当连接成功时this.socketTask.onopen = (res) => {console.log("websocket连接成功!", res);this.is_open_socket = true//连接正常清除重连定时器this.clearReconnect();// this.startHeartbeat();}// 当收到消息时this.socketTask.onmessage = (res) => {console.log(res.data)}// 当连接出错时this.socketTask.onerror = (res) => {console.log("websocket连接出错!", res);this.is_open_socket = false// this.reconnect()}// 当连接关闭时this.socketTask.onclose = (res) => {console.log("websocket已经被关闭了!", res);this.is_open_socket = false// this.reconnect()}}// 发送消息send(value) {if (this.is_open_socket) {this.socketTask.send(value);} else {console.log("无法发送消息:WebSocket未连接");}}// 开启心跳检测startHeartbeat() {this.heartbeatInterval = setInterval(() => {const heartbeatMessage = {value: "测试一下服务器端是否在连接状态",method: "开启心跳机制"};this.send(JSON.stringify(heartbeatMessage)) // 发送心跳消息}, this.time * 1000)}//停止发送心跳stopHeartbeat() {clearInterval(this.heartbeatInterval);}// 清除重连定时器clearReconnect() {clearTimeout(this.reconnectTimeout);}// 重新连接reconnect() {//停止发送心跳this.stopHeartbeat()//如果不是人为关闭的话,进行重连if (!this.is_open_socket) {this.reconnectTimeOut = setTimeout(() => {this.connectSocketInit();}, 3000)}}//外部获取消息getMessage(callback) {this.socketTask.onmessage = (res) => {return callback(res) // 调用外部回调函数处理消息}}
}
export default WebSocketClass;
// 调用方法
// -------------------------------------------------------------------
// 单页面
// import WebSocketClass from '@/network/webSocket';
// let ws = new WebSocketClass("ws:****",5000)
// 发送消息
// let data={value:"传输内容",method:"方法名称"}
// ws.send(JSON.stringify(data));
// 接收消息
// ws.getMessage(res=>{
// 	console.log(res);
// })

可能学习的不够深刻、总结不到位,请谅解。如有误,请指正!
在这里插入图片描述

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

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

相关文章

开源ChatGPT系统源码 采用NUXT3+Laravel9后端开发 前后端分离版本

开源ChatGPT系统源码 采用NUXT3Laravel9后端开发 前后端分离版本 ChatGPT是一种基于AI的聊天机器人技术,它可以帮助用户与聊天机器人进行自然语言交流,以解决用户的问题或满足用户的需求。ChatGPT的核心技术是使用自然语言处理(NLP&#xff…

什么是Flex布局?请列举一些Flex布局的常用属性。

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ Flex布局(Flexible Box Layout)⭐ Flex布局的常用属性⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之…

openCV实战-系列教程7:轮廓检测2与模板匹配(轮廓检测/轮廓特征/轮廓近似/轮廓边界矩阵/轮廓边界圆/模版匹配)、原理解析、源码解读

打印一个图片可以做出一个函数: def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows() 1、轮廓特征与近似 1.1 轮廓特征 前面我们计算了这个图片的轮廓: 它的轮廓信息保存在了contours中,取出第一个轮廓&…

vue element-ui 菜单管理使用图标选择器组件

目录 🌟前言🌟安装🌟main.js配置🌟页面使用🌟效果展示 🌟前言 哈喽小伙伴们,本文为大家介绍一下 VueElementUI 中图标选择器组件的使用方法;一起来看下吧。 🌟安装 np…

一个程序员的工作日记--每天就干两件事,一年后让别人刮目相看

文章目录 成功源于专注一、早上布局二、晚上复盘三、技术细节四、专注与成功五、专注的重要性六、忙碌和赚钱七、结论以嵌入式开发为例:一、早上布局二、晚上复盘三、技术细节四、专注与成功五、忙碌和赚钱六、结论在嵌入式软件开发中,我们需要按照以下步…

Kubernetes(K8S)使用PV和PVC做存储安装mysql

Kubernetes使用PV和PVC做存储安装mysql 环境准备什么是PV和PVC环境准备配置nfs安装nfs配置nfs服务端 创建命名空间配置pv和pvcpv的yaml文件pvc的yaml文件 部署mysql创建mysql的root密码的secret创建mysql部署的yaml部署mysql链接mysql外部链接内部链接 环境准备 首先你需要一个…

redux中间件理解,常见的中间件,实现原理。

文章目录 一、Redux中间件介绍1、什么是Redux中间件2、使用redux中间件 一、Redux中间件介绍 1、什么是Redux中间件 redux 提供了类似后端 Express 的中间件概念,本质的目的是提供第三方插件的模式,自定义拦截 action -> reducer 的过程。变为 actio…

【JavaEE基础学习打卡06】JDBC之进阶学习PreparedStatement

目录 前言一、PreparedStatement是什么二、重点理解预编译三、PreparedStatement基本使用四、Statement和PreparedStatement比较1.PreparedStatement效率高2.PreparedStatement无需拼接参数3.PreparedStatement防止SQL注入 总结 前言 📜 本系列教程适用于JavaWeb初学…

SpringMVC探秘: 实现MVC模式的Web应用

文章目录 1. SpringMVC概述1.1. 什么是SpringMVC?1.1.1. MVC与SpringMVC 1.2. SpringMVC项目的优势 2. SpringMVC项目的创建与使用2.1. 创建SpringMVC项目2.2. 设置路由2.3. 获取参数2.3.1. 获取一个参数2.3.2. 获取多个参数2.3.3. 获取日期参数2.3.4. 参数重命名Re…

mac地址、ip地址、子网掩码、端口

1. mac地址 又称为网络适配器或者网络接口卡NIC,但是现在更多人原因使用更简单的名称"网卡",通过网卡能够是不同的计算机之间相互连接,从而完成数据通信的功能 每一个网卡在出厂的时候 都会给分配到一个编号,类似与身份…

CSS中的vertical-align属性

vertical-align 1.CSS属性 - vertical-align 2.深入理解vertical-align – line boxes This property affects the vertical positioning inside a line box of the boxes generated by an inline-levelelement. 官方文档的翻译:vertical-align会影响 行内块级元素…

Android | 关于 OOM 的那些事儿

作者:345丶 前言 Android 系统对每个app都会有一个最大的内存限制,如果超出这个限制,就会抛出 OOM,也就是Out Of Memory 。本质上是抛出的一个异常,一般是在内存超出限制之后抛出的。最为常见的 OOM 就是内存泄露(大量…

Prompt-“设计提示模板:用更少数据实现预训练模型的卓越表现,助力Few-Shot和Zero-Shot任务”

Prompt任务(Prompt Tasks) 通过设计提示(prompt)模板,实现使用更少量的数据在预训练模型(Pretrained Model)上得到更好的效果,多用于:Few-Shot,Zero-Shot 等…

Spring Boot(Vue3+ElementPlus+Axios+MyBatisPlus+Spring Boot 前后端分离)【二】

😀前言 本篇博文是关于Spring Boot(Vue3ElementPlusAxiosMyBatisPlusSpring Boot 前后端分离)【二】的,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文…

adb shell setprop 、开发者选项

App性能调试详解 Android App性能监控工具 更多系统属性参考 一、开启 GPU Render 的profiling bar: Gpu渲染速度 adb shell setprop debug.hwui.profile true adb shell setprop debug.hwui.profile visual_bars adb shell setprop debug.hwui.profile visual…

基于5G边缘网关的储能在线监测方案

近年以来,光伏、风力、水力发电等产业发展迅速,新能源在电力市场的占比持续增加,已经成为电力系统的重要组成部分。但由于光伏、风力、水力等发电方式存在天然的波动性,因此也需要配套储能、蓄能系统,保障新能源运行和…

股票预测和使用LSTM(长期-短期-记忆)的预测

一、说明 准确预测股市走势长期以来一直是投资者和交易员难以实现的目标。虽然多年来出现了无数的策略和模型,但有一种方法最近因其能够捕获历史数据中的复杂模式和依赖关系而获得了显着的关注:长短期记忆(LSTM)。利用深度学习的力…

UE4/5Niagara粒子特效之Niagara_Particles官方案例:2.4->3.2

之前的案例 UE4/5Niagara粒子特效之Niagara_Particles官方案例:1.1->1.4_多方通行8的博客-CSDN博客 UE4/5Niagara粒子特效之Niagara_Particles官方案例:1.5->2.3_多方通行8的博客-CSDN博客 2.4 Location Events 这次的项目和之…

自动化测试之Selenium

自动化测试Selenium介绍环境搭建如何操作浏览器定位元素css类选择器定位元素xpath定位元素css选择语法xpath选择语法 常用操作添加等待打印信息浏览器更多操作键盘事件鼠标事件特殊场景只选复选框iframe标签下拉框处理弹窗显示上传文件 关闭浏览器切换窗口截图 自动化测试 自动…

JavaSE 认识String类

目录 1 创建字符串2 字符串比较相等3 字符串常量池4 理解字符串不可变5 字符、字节与字符串5.1 字符与字符串5.2 字节与字符串5.3 小结 6 字符串常见操作6.1 字符串比较6.2 字符串查找6.3 字符串替换6.4 字符串拆分6.5 字符串截取6.6 其他操作方法 7 StringBuffer 和 StringBui…