【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 = null
    this.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);
// })

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

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

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

相关文章

5.8.webrtc事件处理基础知识

在之前的课程中呢,我向你介绍了大量web rtc线程相关内容,今天呢,我们来看一下线程事件处理的基本知识。首先,我们要清楚啊,不同的平台处理事件的API是不一样的,这就如同我们当时创建线程是类似的&#xff0…

第12步---MySQL的JDBC操作

第12步---MySQL的JDBC操作 1.概述 采用Java API 的方式实现数据之间的操作。 根据不同的数据库采用了不同的驱动,接口是一致的。 下载的地址 MySQL :: Download MySQL Connector/J (Archived Versions) 2.执行流程 注册驱动 创建连接 执行sql语句的对象 结果…

Kaggle回归问题Mercedes——Benz Greener Manufacturing

目录 前言1 题目介绍2 数据清洗3 数据可视化分析4 模型训练5 源码 前言 这是我在大三选修课的课程设计,内容参考了Kaggle上高赞的代码,有详细批注,整体比较基础,结构相对完整,便于初学者学习。这个是一个回归问题&…

MAC电脑外放没有声音解决方案

烦人呐,我的mac外接显示屏幕,显示器没有音频输出,需要mac笔记本的音频输出,但是经常打开后,mac没有声音输出,需要重启电脑才能生效。亲测一下方法有效,请参考: 文章目录 一、短期方案…

17.4 【Linux】systemctl 针对 timer 的配置文件

有时候,某些服务你想要定期执行,或者是开机后执行,或者是什么服务启动多久后执行等等的。在过去,我们大概都是使用 crond 这个服务来定期处理, 不过,既然现在有一直常驻在内存当中的 systemd 这个好用的东西…

无涯教程-PHP - 常量数组

现在可以使用 define()函数定义数组常量。在PHP 5.6中&#xff0c;只能使用 const 关键字定义它们。 <?php//define a array using define functiondefine(animals, [dog,cat,bird]);print(animals[1]); ?> 它产生以下浏览器输出- cat PHP - 常量数组 - 无涯教程网无…

excel逻辑函数篇1

1、AND(logical1,[logical2],…)&#xff1a;用于测试所有条件是否均为TRUE 检查所有参数均为true&#xff0c;如果是则返回true 2、OR(logical1,[logical2],…)&#xff1a;用于测试是否有为TRUE的条件 如果任意参数值为true&#xff0c;即返回true&#xff1b;只有当所有参数…

673. 最长递增子序列的个数

673. 最长递增子序列的个数 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;方法一&#xff1a;动态规划方法二&#xff1a;贪心 前缀和 二分查找 参考代码&#xff1a;__673最长递增子序列的个数__动态规划__673最长递增子序列的个数__贪心_前缀和_二分查找…

ChatGPT 随机动态可视化图表分析

动态可视化图表分析实例如下图&#xff1a; 这样的动态可视化图表可以使用ChatGPT OpenAI 来实现。 给ChatGPT发送指令&#xff1a; 你现在是一个数据分析师&#xff0c;请使用HTML&#xff0c;JS&#xff0c;Echarts&#xff0c;来完成一个动态条形图&#xff0c;条形图方向横…

汽车电子笔记之:AUTOSA架构下的OS概述

目录 1、实时操作系统&#xff08;RTOS&#xff09; 2、OSEK操作系统 2.1、OSEK概述 2.2、OSEK处理等级 2.3、OSEK任务符合类 2.4、OSEK优先级天花板模式 3、AUTOSAR OS 3.1、 AUTOSAR OS对OSEK OS的继承和扩展 3.2、AUTOSAR OS的调度表 3.3、AUTOSAR OS的时间保护 3…

OS 内核级线程

用户级线程是两个栈&#xff0c;核心级线程是两套栈&#xff0c;用户栈和内核栈 用户级是并发&#xff08;同时触发、交替执行&#xff09;&#xff0c;这个是并行&#xff08;同时触发可以同时执行&#xff09; 进入内核的唯一方式是中断 根据TCB的切换&#xff0c;实现内核…

C++11特性详解

一、简介 在C11标准出来之前&#xff0c;一直是C98/03标准占引领地位&#xff0c;而C98/03标准是C98标准在2003年将存在的一些漏洞进行了修复&#xff0c;但并没有核心语法的改动。相比于C98/03&#xff0c;C11则带来了数量可观的变化&#xff0c;其中包含了约140个新特性&…

深度学习处理文本(NLP)

文章目录 引言1. 反向传播1.1 实例流程实现1.2 前向传播1.3 计算损失1.4 反向传播误差1.5 更新权重1.6 迭代1.7 BackPropagation & Adam 代码实例 2. 优化器 -- Adam2.1 Adam解析2.2 代码实例 3. NLP任务4. 神经网络处理文本4.1 step1 字符数值化4.2 step 2 矩阵转化为向量…

HTML基础知识点

目录 ​编辑一、使用 vscode 二、研究代码的特点 三、HTML 常见标签 注释标签 标题标签 段落标签 换行标签 格式化标签 图片标签 超链接标签 表格标签 列表标签 表单标签&#xff1a; form 标签 input标签&#xff1a; select textarea标签&#xff1a; 无语…

【stable-diffusion使用扩展+插件和模型资源(下)】

插件模型魔法图片等资源&#xff1a;https://tianfeng.space/1240.html 书接上文&#xff1a;&#xff08;上&#xff09; 插件推荐 1.lobe theme lobe theme是一款主题插件&#xff0c;直接可以在扩展安装 界面进行了重新布局&#xff0c;做了一些优化&#xff0c;有兴趣的…

HDLBits-Verilog学习记录 | Verilog Language-Vectors

文章目录 11.vectors | vector012.vectors in more detail | vector113.Vector part select | Vector214.Bitwise operators | Vectorgates15.Four-input gates | Gates416.Vector concatenation operator | Vector317.Vector reversal 1 | Vectorr18. Replication operator | …

平衡二叉树的插入和删除(从现在开始摆脱旋转)

平衡二叉树是指任意节点的左子树和右子树高度之差的绝对值不超过1 一.插入操作 1.找到合适位置插入 2.从下到上&#xff0c;沿着插入节点与根节点的连线&#xff0c;找到不平衡的二叉树 以68为根节点的二叉树平衡&#xff0c;左右子树高度差为1 以60为根节点的二叉树不平衡&a…

【Adobe After Effects】关于ae点击空格不会播放反而回退一帧的解决方案

最近玩ae的时候遇见了一个小问题&#xff0c;就是有时候敲空格&#xff0c;视频没办法播放&#xff0c;反而会回退一帧&#xff0c;经过摸索发现了一个解决办法&#xff1a; 点击编辑---首选项 然后选择“音频硬件” 然后选择正确的默认输出&#xff0c;点击确定即可

Android 13 - Media框架(6)- NuPlayer::Source

Source 在播放器中起着拉流&#xff08;Streaming&#xff09;和解复用&#xff08;demux&#xff09;的作用&#xff0c;Source 设计的好坏直接影响到播放器的基础功能&#xff0c;我们这一节将会了解 NuPlayer 中的通用 Source&#xff08;GenericSource&#xff09;关注本地…

【LeetCode】224. 基本计算器

224. 基本计算器&#xff08;困难&#xff09; 方法&#xff1a;双栈解法 思路 我们可以使用两个栈 nums 和 ops 。 nums &#xff1a; 存放所有的数字ops &#xff1a;存放所有的数字以外的操作&#xff0c;/- 也看做是一种操作 然后从前往后做&#xff0c;对遍历到的字符做…