【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.rhkb.cn/news/104672.html

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

相关文章

vscode C++17便捷配置教程(懒人版)

环境链接 以上是已经配置好的c17环境链接,直接下载解压即可(注意文件路径上不要带有中文) 下载解压之后按照msys64-mingw64-bin路径打开 然后单击该路径右方空白区域可直接复制路径 然后点击开始菜单搜索“环境变量“并打开(如…

SQL阶段性优化

😜作 者:是江迪呀✒️本文关键词:MySQL、SQL优化、阶段性优化☀️每日 一言:我们要把懦弱扼杀在摇篮中。 一、前言 我们在做系统的过程中,难免会遇到页面查询速度慢,性能差的问题,…

数据结构基础:P3-树(上)----编程作业02:List Leaves

本系列文章为浙江大学陈越、何钦铭数据结构学习笔记,系列文章链接如下: 数据结构(陈越、何钦铭)学习笔记 文章目录 一、题目描述二、整体思路与实现代码 一、题目描述 题目描述: 给定一棵树,按照从上到下、从左到右的顺序列出所有…

Compressor For Mac强大视频编辑工具 v4.6.5中文版

Compressor for Mac是苹果公司推出的一款视频压缩工具,可以将高清视频、4K视频、甚至是8K视频压缩成适合网络传输或存储的小文件。Compressor支持多种视频格式,包括H.264、HEVC、ProRes和AVC-Intra等,用户可以根据需要选择不同的压缩格式。 …

ModaHub魔搭社区:WinPlan经营大脑预算编制

目录 WinPlan经营大脑预算编制介绍 WinPlan经营大脑预算编制模版 WinPlan经营大脑预算模版管理 WinPlan经营大脑预算数据录入 WinPlan经营大脑预算编制介绍 预算编制时面向企业经营管理场景,创建各个业务单位的目标,包括销售目标、财务目标、人事目标等,实现各个业务单…

华为OD机试 - 最佳植树距离 - 二分查找(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、备注说明五、二分查找六、解题思路七、Java算法源码八、效果展示1、输入2、输出3、说明 一、题目描述 按照环保公司要求,小明需要在沙化严重的地区进行植树防沙工作,初步目标是种植一条直线的树带。 由于…

腾讯云和阿里云服务器折扣对比_看看哪家划算?

阿里云服务器和腾讯云服务器根据购买时长可以享受一定的优惠折扣,综合对比下来腾讯云折扣更低,阿腾云来对比下阿里云和腾讯云的云服务器根据购买时长可以享受的常规折扣对比: 目录 阿里云和腾讯云折扣对比 阿里云服务器常规折扣 腾讯云服…

CentOS KVM虚拟安装和开机启动

1. 配置系统 关闭SELinux setenforce 0持久化关闭配置 vi /etc/selinux/config2. 安装虚拟化软件 安装 KVM、QEMU等虚拟化软件。 yum install qemu-kvm qemu-img virt-manager libvirt virt-install virt-viewer 检查LVM模块是否已经加载 lsmod |grep kvm设置开机启动 s…

C语言:选择+编程(每日一练Day8)

目录 选择题: 题一: 题二: 题三: 题四: 题五: 编程题: 题一:字符个数统计 思路一: 题二:多数元素 思路一: 本人实力有限可能对一些…

JavaScript中的this关键字的作用,以及它如何确定其值

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ this关键字的作用⭐ this的值取决于执行上下文⭐ 示例⭐ 总结⭐ 写在最后 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这…

1448. 统计二叉树中好节点的数目(C++题解)

1448. 统计二叉树中好节点的数目 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。 示例 1: 输入:root [3,1,4,3,nu…

androidStudio或IDEA的通过gitBash打开插件

本人,一个资深的命令行,业余爱好者。常年直接vim,或者shell上服务器阅读代码。比较偏好使用GitBash来打开项目,进行git status,git diff,git add,commit等动作。 基于以上原因,本人开…

【Linux】【驱动】第一个相对完整的驱动编写

【Linux】【驱动】第一个相对完整的驱动编写 续1.驱动部分的代码2 app 代码3 操作相关的代码 续 这个章节会讲述去直接控制一个GPIO,高低电平。 因为linux不允许直接去操作寄存器,所以在操作寄存器的时候就需要使用到函数:ioremap 和iounma…

多功能租车平台微信小程序源码 汽车租赁平台源码 摩托车租车平台源码 汽车租赁小程序源码

多功能租车平台微信小程序源码是一款用于汽车租赁的平台程序源码。它提供了丰富的功能,可以用于租赁各种类型的车辆,包括汽车和摩托车。 这个小程序源码可以帮助用户方便地租赁车辆。用户可以通过小程序浏览车辆列表,查看车辆的详细信息&…

Centos7 交叉编译QT5.9.9源码 AArch64架构

环境准备 centos7 镜像 下载地址:http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/ aarch64交叉编译链 下载地址:https://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/ QT5.9.9源代码 下载地址&#xff1…

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

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

vue 展开和收起

效果图 代码块 <div><span v-for"(item,index) in showHandleList" :key"item.index"><span>{{item.emailFrom}}</span></span><span v-if"this.list.length > 4" click"showAll !showAll">{…

Codeforces Round #894 (Div.3)

文章目录 前言A. Gift Carpet题目&#xff1a;输入&#xff1a;输出&#xff1a;思路&#xff1a;代码&#xff1a; B. Sequence Game题目&#xff1a;输入&#xff1a;输出&#xff1a;思路&#xff1a;代码&#xff1a; C. Flower City Fence题目&#xff1a;输入&#xff1a…

Java之AbstractQueuedSynchronizer

要让你写一个java版的并发同步库&#xff0c;你会怎么思考设计&#xff1f;&#xff1f;&#xff1f;先思考三五分钟 请先拜读下老外的paperhttp://gee.cs.oswego.edu/dl/papers/aqs.pdf 1. 简介 AbstractQueuedSynchronizer&#xff0c;简称AQS&#xff0c;中文翻译为抽象队…

Linux 多线程解决客户端与服务器端通信

一、一个服务器端只能和一个客户端进行通信&#xff08;单线程模式&#xff09; 客户端代码ser.c如下&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/socket.h> #include<netinet…