WebSocket真实项目总结

websocket

websocket是什么?

websocket是一种网络通讯协议。 websocket 是HTML5开始提供的一种在单个TCP链接上进行全双工通讯的协议。

为什么需要websocket?

初次接触websocket,都会带着疑惑去学习,既然已经有了HTTP协议,为什么还需要另一个协议?它能带来什么好处呢?很简单,因为HTTP协议的通讯只能由客户端发起。
举列来说,我想了解今天的天气,只能是客户端向服务端发出请求,服务器返回查询结果,HTTP协议做不到服务器主动向客户端推送信息。

为什么需要websocket

传统的HTTP协议是无状态的,每次请求request都要由客户端浏览器主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据了这种客户端是主动方,服务端是被动方的传统web模式,对于信息变化不频繁的web应用来说造成的麻烦较小,而对于涉及实时信息的web应用却带来了很大的不方便,如带有即时通信,实时数据,订阅推送等功能的应用。

为什么需要websocket

websocket的优势

相对于传统HTTP每次请求-应答都需要客户端与服务端简历连接的模式,websocket是类似socket的TCP长连接通讯模式,一旦websocket连接建立后,后继数据都已帧序列的形式传输,在客户端断开websocket连接活Server端终端连接前,不需要客户端和服务端重新发起连接请求,在海量并发及客户端与服务器交互负载流量大的情况下,极大的节省了网络带宽资源的消耗,有明显的性能优势,且客户端发送和接受消息实在同一个持久连接上发起,实时性优势明显。

websocket实现方式

websocket需要像TCP一样,先建立连接,需要客户端和服务端进行握手连接,连接成功后才能湘湖通信。

websocket构造函数

websocket对象作为一个构造函数,用于新建websocket实例

var ws = new webSocket("ws://127.0.0.1:8090")

执行上面语句之后,客户端就会与服务器进行连接。

webSocket.readyState

readyState属性返回实例对象的当前状态,共有四种。

CONNECTING:值为0,表示正在连接。
OPEN:值为1,标识连接成功,可以通信了。
CLOSING:值为2,标识连接正在关闭。
CLOSED:值为3,标识连接已经关闭,或者打开链接失败。

webSocket.onerror

连接发生错误的回调方法

ws.onerror = function(){
	alert("webSocket连接发生错误“)
}

webSocket.onclose

实例对象的onclose 属性,用于指定关闭连接后的回调函数

ws.onclose = function(){
	alert("websocket连接关闭")
}

webSocket.send()

实例对象的send()方法用于向服务器发送数据

ws.send("your message")

总结完webSocket如何握手及其所有的方法,下面进入实战

使用websocket实现图表数据动态实时更新

websocket 封装的websocket.js代码
/* WebSocket封装
 * @param url: WebSocket接口地址与携带参数必填
 * @param onOpenFunc: WebSocket的onopen回调函数,如果不需要可传null
 * @param onMessageFunc: WebSocket的onmessage回调函数,如果不需要可传null
 * @param onCloseFunc: WebSocket的onclose回调函数,如果不需要可传null
 * @param onErrorFunc: WebSocket的onerror回调函数,如果不需要可传null
 * @param heartMessage: 发送后台的心跳包参数,必填 (给服务端的心跳包就是定期给服务端发送消息)
 * @param timer: 给后台传送心跳包的间隔时间,不传时使用默认值3000毫秒
 * @param isReconnect: 是否断掉立即重连,不传true时不重连
 */
function useWebSocket(
    url,
    onOpenFunc,
    onMessageFunc,
    onCloseFunc,
    onErrorFunc,
    heartMessage,
    timer,
    isReconnect
  ) {
    let isConnected = false; // 设定已链接webSocket标记
    // websocket对象
    let ws = null;
    // 创建并链接webSocket
    let connect = () => {
      // 如果未链接webSocket,则创建一个新的webSocket
      if (!isConnected) {
        ws = new WebSocket(url);
        isConnected = true;
      }
    };
    // 向后台发送心跳消息
    let heartCheck = () => {
      // for (let i = 0; i < heartMessage.length; i++) {
      //   ws.send(JSON.stringify(heartMessage[i]))
      // }
    };
    // 初始化事件回调函数
    let initEventHandle = () => {
      ws.addEventListener('open', (e) => {
        console.log('onopen', e);
        // 给后台发心跳请求,在onmessage中取得消息则说明链接正常
        //heartCheck()
        // 如果传入了函数,执行onOpenFunc
        if (!onOpenFunc) {
          return false;
        } else {
          onOpenFunc(e, ws);
        }
      });
      ws.addEventListener('message', (e) => {
        // 接收到任何后台消息都说明当前连接是正常的
        if (!e) {
          console.log('get nothing from service');
          return false;
        } else {
          // 如果获取到后台消息,则timer毫秒后再次发起心跳请求给后台,检测是否断连
          setTimeout(
            () => {
              if (isConnected) {
                heartCheck();
              }
            },
            !timer ? 3000 : timer
          );
        }
        // 如果传入了函数,执行onMessageFunc
        if (!onMessageFunc) {
          return false;
        } else {
          onMessageFunc(e);
        }
      });
      ws.addEventListener('close', (e) => {
        console.log('onclose', e);
        // 如果传入了函数,执行onCloseFunc
        if (!onCloseFunc) {
          return false;
        } else {
          onCloseFunc(e);
        }
        // if (isReconnect) { // 如果断开立即重连标志为true
        //   // 重新链接webSocket
        //   connect()
        // }
      });
      ws.addEventListener('error', (e) => {
        console.log('onerror', e);
        // 如果传入了函数,执行onErrorFunc
        if (!onErrorFunc) {
          return false;
        } else {
          onErrorFunc(e);
        }
        if (isReconnect) {
          // 如果断开立即重连标志为true
          // 重新链接webSocket
          connect();
        }
      });
    };
    // 初始化webSocket
    // (() => {
    // 1.创建并链接webSocket
    connect();
    // 2.初始化事件回调函数
    initEventHandle();
    // 3.返回是否已连接
    return ws;
    // })()
  }
  
  export default {
    useWebSocket,
  };
  
  

调用方法并建立连接使用:(当连接失败后,进行websocket重连)

initWebSocket() {
      if(!this.ws) {
      	// url
        let url = 'ws://XXX.XXX.XXX.XXX:4002/websocket/11111'
        this.ws = websocket.useWebSocket(
          url,	// url
          this.wsOnOpen, // 链接回调
          this.wsOnMessage,	// 连接成功后处理接口返回信息
          this.wsOnClose, // 关闭回调
          this.wsOnError, // 消息通知错误回调
          [], // 发送后台的心跳包参数
          null, // 给后台传送心跳包的间隔时间
          true, // 是否断掉立即重连
        );
      }
    },
    wsOnOpen() {
      console.log('开始连接')
    },
    wsOnError(e) {
      console.log(e,'消息通知错误回调,重新连接')
      this.ws.close();
      this.ws = null;
      this.initWebSocket();
    },
    wsOnMessage(e) {
      if(e.data != '连接成功') {
		    console.log(JSON.parse(e.data),'接口返回信息')
      }
    },
    wsOnClose() {
      console.log('关闭')
      // 意外关闭之后重新连接
      if(!this.disConnectTimer) {
        this.disConnectTimer = setTimeout(() => {
          this.initWebSocket()
          this.disConnectTimer = null
        }, 10000)
      }
    },

实现效果:
websocket实时图表
重连效果
websocket关闭重连效果
完结~

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

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

相关文章

【nlp】2.2 传统RNN模型

传统RNN模型 1 传统RNN模型1.1 RNN结构分析1.2 使用Pytorch构建RNN模型1.3 传统RNN优缺点1 传统RNN模型 1.1 RNN结构分析 结构解释图: 内部结构分析: 我们把目光集中在中间的方块部分, 它的输入有两部分, 分别是h(t-1)以及x(t), 代表上一时间步的隐层输出, 以及此时间步的…

BUUCTF 假如给我三天光明 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;解压得到一个zip压缩包和一张.jpg图片。 密文&#xff1a; 解题思路&#xff1a; 其实做CTF题时&#xff0c;一定要紧紧的盯着那些明显的事物&#xff0c;优先解决它们&#xff0c;而不是浪…

振南技术干货集:深入浅出的Bootloader(1)

注解目录 1、烧录方式的更新迭代 1.1 古老的烧录方式 (怀旧一下&#xff0c;单片机高压烧录器。) 1.2 ISP 与ICP 烧录方式 (还记得当年我们玩过的 AT89S51?) 1.3 更方便的 ISP 烧录方式 1.3.1串口 ISP &#xff08;是 STC 单片机成就了我们&#xff0c;还是我们成就了…

Ulimit -系统资源配额配置说明

Linux 对于每个用户&#xff0c;系统限制其最大进程数&#xff0c;为提高性能&#xff0c;可以根据设备资源情况&#xff0c; 设置个Linux用户的最大进程数&#xff0c;一些需要设置为无限制&#xff1b; ulimit 参数说明 选项 含义 例子 -H 设置硬资源限制&#xff0c;一旦…

个体诊所电子处方系统设计,诊所电子处方模板,药店电子处方系统,佳易王电子处方管理系统V16.0下载

个体诊所电子处方系统设计&#xff0c;诊所电子处方模板&#xff0c;药店电子处方系统&#xff0c;佳易王电子处方管理系统V16.0下载 软件支持配方模板&#xff0c;病人病历记录查询等&#xff0c;软件打印处方单所用的纸张为 A5纸。软件可以下载试用&#xff0c;点击最下方官网…

道路交通仿真方案【SUMO + TraCI + Python】

“城市交通模拟”&#xff08;SUMO&#xff09;是一个开源、高度可移植、微观和连续的交通模拟包&#xff0c;旨在处理大型网络&#xff08;SUMO 文档&#xff09;。 TraCI 是“交通控制接口”模块的简称&#xff0c;它可以访问正在运行的道路交通模拟&#xff0c;以检索模拟对…

一文图解爬虫姊妹篇(spider)

—引导语 爬虫&#xff0c;没有一个时代比当前更重视它。一个好的爬虫似乎可以洞穿整个互联网&#xff0c;“来装满自己的胃”。 接上一篇&#xff1a;一文图解爬虫&#xff08;spider&#xff09; 博主已初步对爬虫的“五脏六腑”进行了解剖。虽然俗称“爬虫”&#xff0c;但窃…

3.3 Linux 文件管理

1、查看系统信息 tty 命令 描述&#xff1a;查看当前系统在哪个终端语法&#xff1a;tty Linux默认情况下提供6个虚拟终端来让用户登录&#xff0c;系统将F1~F6定义为tty1~tty6。 ctrlalt(F1~F6) &#xff1a;从图形界面切换到命令行界面的第 n 个虚拟终端&#xff08;F1 是…

VS Code二进制查阅插件Hex Editor(附ASCII表)

文章目录 Hex EditorASCII Hex Editor Hex Editor是一款强大的二进制读取插件&#xff0c;安装之后&#xff0c;可以直接把二进制文件拖入VS Code&#xff0c;然后点击仍然打开按钮&#xff0c;选择Hex Editor&#xff0c;就可以看到二进制数据了&#xff0c;效果如下 点击任何…

代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和

代码随想录算法训练营第五十三天 | LeetCode 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和 文章链接&#xff1a;最长公共子序列、不相交的线、最大子数组和 视频链接&#xff1a;最长公共子序列、不相交的线、最大子数组和 1. LeetCode 1143. 最长公共子序列 1…

LTspice导入spice模型

一、创建原理图&#xff08;原件的样子&#xff09; 1、下载spice模型 2、用LTspice打开spice模型 3、选中模型名称&#xff0c;选择创建 4、可以自己画模型 导入后都是方块的&#xff0c;可以自己画模型的样子&#xff0c;所有引脚和模型名称都跟器件一样可以移动 da 画模…

微服务系列-使用 RestTemplate 的 Spring Boot 微服务通信示例

公众号「架构成长指南」&#xff0c;专注于生产实践、云原生、分布式系统、大数据技术分享。 概述 下面我们将学习如何创建多个 Spring boot 微服务以及如何使用 RestTemplate 类在多个微服务之间进行同步通信。 微服务通信有两种风格&#xff1a; 同步通讯异步通信 同步通…

【C++初阶(六)】类和对象(中)与日期类的实现

本专栏内容为&#xff1a;C学习专栏&#xff0c;分为初阶和进阶两部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握C。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&…

如何挑选RPA开发商?

其实&#xff0c;只要在这个行业调查的时间足够&#xff0c;不难发现里面有很多弯弯绕绕。 首先&#xff0c;RPA厂商虽然很多&#xff0c;但是优秀的RPA厂商就那么几家&#xff0c;它们都有各自擅长的领域&#xff0c;像金智维&#xff0c;就是在金融领域、政务领域&#xff1…

【Python3】【力扣题】268. 丢失的数字

【力扣题】题目描述&#xff1a; 【Python3】代码&#xff1a; 1、解题思路&#xff1a;哈希。元素去重&#xff0c;依次判断是否在0-n内&#xff0c;没有则返回。 知识点&#xff1a;set(...)&#xff1a;转为集合&#xff0c;集合中的元素不重复。 class Solution:def mis…

打破语言壁垒,实现全球商贸:多语言多商户跨境商城源码引领电商新潮流

随着全球化的不断深入&#xff0c;电子商务的蓬勃发展&#xff0c;传统的单语言电商模式已经无法满足日益多元化的市场需求。多语言多商户跨境商城源码&#xff0c;一种创新的电商解决方案&#xff0c;应运而生。它打破了语言和地域的限制&#xff0c;让全球的商家和消费者都能…

uniapp打包安卓app获取包名

uniapp打包安卓app获取包名的两种方式 1.uniapp云打包 这上面直接可以看到包名&#xff0c;可以修改&#xff0c;也可以在 manifest.json 文件中配置修改 package配置的就是包名&#xff0c;要确保唯一性 2.使用aapt工具获取 1.下载aapt工具&#xff0c;然后添加到环境变量…

tcpdump wireshark简单使用

tcpdump工作原理 tcpdump 是 Linux 系统中非常有用的网络工具&#xff0c;运行在用户态&#xff0c;本质上是通过调用 libpcap 库的各种 api 来实现数据包的抓取功能&#xff0c;利用内核中的 AF_PACKET 套接字&#xff0c;抓取网络接口中传输的网络包。查 看 tcpdump 的 手册…

驱动程序编进内核或则编成模块

驱动程序可以编进内核或则编成模块 驱动程序编成模块 打开/home/book/100ask_imx6ull-sdk/Linux-4.9.88/drivers/char/Kconfig文件&#xff0c;添加以下信息。 在/home/book/100ask_imx6ull-sdk/Linux-4.9.88在目录下使用make memuconfig命令查看配置菜单。 可以按/&#…

二叉树理论碎碎记

二叉树的种类 在刷题的过程中&#xff0c;我们主要关注两种主要形式&#xff1a;满二叉树和完全二叉树。 满二叉树 如果一棵二叉树只有度为0的结点和度为2的结点&#xff0c;并且度为0的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。如下图所示&#xff1a;这棵二叉…