js实现websocket断线重连功能

在项目开发中我们可能经常要使用websocket技术,当连接发生断线后,如果不进行页面刷新将不能正常接收来自服务端的推送消息。为了有效避免这种问题,我们需要在客户端做断线重连处理。当网络或服务出现问题后,客户端会不断检测网络状态,如果服务恢复,客户端则会自动重新连接,并断开本地检测网络的定时器。

一、未做断线检测情况

  • 1、项目效果

通过控制台可看到一旦连接关闭,将无法再次收到来自服务器的推送消息。

在这里插入图片描述

  • 2、未整改前代码

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>排队叫号系统</title><link rel="stylesheet" href="/app/admin/component/pear/css/pear.css" /><link rel="stylesheet" href="/app/admin/admin/css/reset.css" />
</head>
<style>html{font-size:14px}.pear-container{background-color: #0d48ff;//background-color: #2e6fff}*{color:white;}.layui-row{width: 100%;}body{position: absolute;}.call-footer {left: 0;bottom: 0;position: fixed;text-align: center;padding: 10px;font-size: 16px;}.call-header{display: flex;justify-content: space-between;line-height: 40px;text-align: center;border-bottom: 2px dashed #85b8b6;}.isemer{color: red;}.call-header>div{font-size: 30px;font-family: "楷体","YaHei Consolas Hybrid", Consolas, "微软雅黑", "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, "Monaco", courier, monospace;font-weight: 800;}#hd-logo>img{width: 200px;}#hd-title {font-size: 24px;}#hd-desc{font-size: 14px;}/*设置显示当前呼叫患者信息*/#call-place{height: 28px;text-align: center;line-height: 28px;font-size: 18px;//color: #6fc9cc;border-bottom: 2px dashed #85b8b6;}.dis-dept{display: flex;justify-content:flex-start;font-size: 28px;align-items: center;}.disp-title{display: flex;justify-content: center;align-items: center;text-align: center;padding-right:30px;border-right: 3px dashed #21f3ff;margin-top: 20px;min-width: 200px;height: 75vh;}.disp-title-content{flex:1;display: flex;justify-content: center;align-items: center;text-align: center;font-size: 120px;border: 10px solid #f8fff7;border-radius: 50%;line-height: 100%;width: 180px;height: 180px;}.disp-content{flex:1;display: flex;justify-content: center;align-items: center;height: 75vh;padding-left: 20px;}/*字体大小设置*/.dispc-text{font-size: 60px;overflow: hidden;}.layui-layer{z-index: 9999; /*保证在最上层*/background-color: rgba(0,0,0,0.5); /*背景半透明*/}@keyframes twinkle {0% {opacity: 0.9;}100% {opacity: 0.2;}}</style>
<body class="pear-container"><div class="layui-fluid" ><div class="row call-header"><div id="hd-logo"><img src="/app/admin/upload/files/20231128/656599ce1fd4.png" alt=""></div><div id="hd-title">1号窗口</div><div id="hd-desc">2023-11-28 15:00:00</div></div><div style="display: none" class="row" id="call-place">请C003号 王小宝到1号窗口采血</div><div class="layui-row"  id="call-display"><div class="dis-dept"><div class="disp-title"><div class="disp-title-content"><?php echo $config['num'];?></div></div><div class="disp-content" id="disp-con-htm"><!--<marquee direction="up">--><div class="dispc-text">尚未呼叫 <br></div><!--</marquee>--></div></div></div></div>
<div class="layui-row call-footer" >请保持安静,耐心等待呼叫!
</div><script src="/app/admin/component/layui/layui.js"></script>
<script src="/app/admin/component/pear/pear.js"></script>
<script src="/app/admin/admin/js/common.js"></script>
<script src="/app/queue/component/tools.js"></script>
<script src="/app/queue/component/rpm2h5.js"></script>
<script>//=========定义显示时间功能结束===================function clock() {var time = new Date().toLocaleString();var htm = '<i class="fa fa-clock-o"></i>' + time;document.getElementById('hd-desc').innerHTML=htm;};setInterval("clock()", 1000);
</script>
<script>var socket = "";var token = "room"+readQueryVariable('id','1');console.log(token);// var isUpdate = readQueryVariable('isUpdate','0');//  var ws_url = "ws://192.168.40.100:7272?token="+token;var ws_url = "ws://192.168.40.100:7272?token="+token;var callMark = "就诊";layui.use(["table", "form", "common", "popup", "util","layer"], function() {let table = layui.table;let form = layui.form;let $ = layui.$;let common = layui.common;let util = layui.util;let layer = layui.layer;var loopTimes = 0 ;// 创建一个新的WebSocket对象var socket = new WebSocket(ws_url);// 连接打开时执行的函数socket.onopen = function(event) {console.log("已成功连接到服务器");// 发送一个消息给服务器//socket.send("你好,服务器!");};// 接收到服务器消息时执行的函数socket.onmessage = function(event) {loopTimes++;console.log("从服务器接收到的消息: " + event.data);};// 当连接关闭时执行的函数socket.onclose = function(event){console.log("连接已关闭");};// 当出现错误时执行的函数socket.onerror = function(error) {console.log("发生错误: " + error);};})</script>
</body>

二、做了断线检测情况

  • 1、重连效果

通过控制台观察可发现,在客户端连接成功后,可接收到服务端推送过来的消息,当服务端关闭后,会触发自动重连定时器,当定时器检测到服务连接成功后,会自动完成连接,并可正常接收来自服务端推送的消息。

在这里插入图片描述

  • 2、支持断线重连完整代码

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>排队叫号系统</title><link rel="stylesheet" href="/app/admin/component/pear/css/pear.css" /><link rel="stylesheet" href="/app/admin/admin/css/reset.css" />
</head>
<style>html{font-size:14px}.pear-container{background-color: #0d48ff;//background-color: #2e6fff}*{color:white;}.layui-row{width: 100%;}body{position: absolute;}.call-footer {left: 0;bottom: 0;position: fixed;text-align: center;padding: 10px;font-size: 16px;}.call-header{display: flex;justify-content: space-between;line-height: 40px;text-align: center;border-bottom: 2px dashed #85b8b6;}.isemer{color: red;}.call-header>div{font-size: 30px;font-family: "楷体","YaHei Consolas Hybrid", Consolas, "微软雅黑", "Meiryo UI", "Malgun Gothic", "Segoe UI", "Trebuchet MS", Helvetica, "Monaco", courier, monospace;font-weight: 800;}#hd-logo>img{width: 200px;}#hd-title {font-size: 24px;}#hd-desc{font-size: 14px;}/*设置显示当前呼叫患者信息*/#call-place{height: 28px;text-align: center;line-height: 28px;font-size: 18px;//color: #6fc9cc;border-bottom: 2px dashed #85b8b6;}.dis-dept{display: flex;justify-content:flex-start;font-size: 28px;align-items: center;}.disp-title{display: flex;justify-content: center;align-items: center;text-align: center;padding-right:30px;border-right: 3px dashed #21f3ff;margin-top: 20px;min-width: 200px;height: 75vh;}.disp-title-content{flex:1;display: flex;justify-content: center;align-items: center;text-align: center;font-size: 120px;border: 10px solid #f8fff7;border-radius: 50%;line-height: 100%;width: 180px;height: 180px;}.disp-content{flex:1;display: flex;justify-content: center;align-items: center;height: 75vh;padding-left: 20px;}/*字体大小设置*/.dispc-text{font-size: 60px;overflow: hidden;}.layui-layer{z-index: 9999; /*保证在最上层*/background-color: rgba(0,0,0,0.5); /*背景半透明*/}@keyframes twinkle {0% {opacity: 0.9;}100% {opacity: 0.2;}}</style>
<body class="pear-container"><div class="layui-fluid" ><div class="row call-header"><div id="hd-logo"><img src="/app/admin/upload/files/20231128/656599ce1fd4.png" alt=""></div><div id="hd-title">1号窗口</div><div id="hd-desc">2023-11-28 15:00:00</div></div><div style="display: none" class="row" id="call-place">请C003号 王小宝到1号窗口采血</div><div class="layui-row"  id="call-display"><div class="dis-dept"><div class="disp-title"><div class="disp-title-content"><?php echo $config['num'];?></div></div><div class="disp-content" id="disp-con-htm"><!--<marquee direction="up">--><div class="dispc-text">尚未呼叫 <br></div><!--</marquee>--></div></div></div></div>
<div class="layui-row call-footer" >请保持安静,耐心等待呼叫!
</div><script src="/app/admin/component/layui/layui.js"></script>
<script src="/app/admin/component/pear/pear.js"></script>
<script src="/app/admin/admin/js/common.js"></script>
<script src="/app/queue/component/tools.js"></script>
<script src="/app/queue/component/rpm2h5.js"></script>
<script>//=========定义显示时间功能结束===================function clock() {var time = new Date().toLocaleString();var htm = '<i class="fa fa-clock-o"></i>' + time;document.getElementById('hd-desc').innerHTML=htm;};setInterval("clock()", 1000);
</script>
<script>var socket = "";var token = "room"+readQueryVariable('id','1');console.log(token);// var isUpdate = readQueryVariable('isUpdate','0');//  var ws_url = "ws://192.168.40.100:7272?token="+token;var ws_url = "ws://192.168.40.100:7272?token="+token;var callMark = "就诊";layui.use(["table", "form", "common", "popup", "util","layer"], function() {let table = layui.table;let form = layui.form;let $ = layui.$;let common = layui.common;let util = layui.util;let layer = layui.layer;var loopTimes = 0 ;function connectWS(){try{socket = new WebSocket(ws_url);// 连接打开时执行的函数socket.onopen = function(event) {console.log("已成功连接到服务器");// 发送一个消息给服务器socket.send(token);};// 接收到服务器消息时执行的函数socket.onmessage = function(event) {console.log("从服务器接收到的消息: " + event.data);};// 当连接关闭时执行的函数socket.onclose = function(event){console.log("连接已关闭");reConnect();};// 当出现错误时执行的函数socket.onerror = function(error) {console.log("发生错误: " + error);};}catch(ex){console.log(ex.message);}};// 调用链接socket函数connectWS();// 断线重新连接websocketfunction reConnect(){let timeId =  setInterval(function(){console.log("正在努力重连。。。");if(socket.readyState===WebSocket.CLOSED){connectWS();// 重新连接成功后清除定时器clearInterval(timeId);}},3000);}})
</script>
</body>

希望各位小伙伴们都能学会了!

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

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

相关文章

Tomcat部署flowable出现consider increasing the maximum size of the cache

使用Apache Tomcat/8.5.32部署运行flowable-6.5.0时发现控制台有警告 问题原因&#xff1a;解决方法: 使用Apache Tomcat/8.5.32部署运行flowable-6.5.0时发现控制台有警告 01-Apr-2024 20:55:08.877 警告 [localhost-startStop-1] org.apache.catalina.webresources.Cache.ge…

二百二十九、离线数仓——离线数仓Hive从Kafka、MySQL到ClickHouse的完整开发流程

一、目的 为了整理离线数仓开发的全流程&#xff0c;算是温故知新吧 离线数仓的数据源是Kafka和MySQL数据库&#xff0c;Kafka存业务数据&#xff0c;MySQL存维度数据 采集工具是Kettle和Flume&#xff0c;Flume采集Kafka数据&#xff0c;Kettle采集MySQL数据 离线数仓是Hi…

【Mysql】一文解读【事务】-【基本操作/四大特性/并发事务问题/事务隔离级别】

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C Linux的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的…

前端调试工具之Chrome Elements、Network、Sources、TimeLine调试

常用的调试工具有Chrome浏览器的调试工具&#xff0c;火狐浏览器的Firebug插件调试工具&#xff0c;IE的开发人员工具等。它们的功能与使用方法大致相似。Chrome浏览器简洁快速&#xff0c;功能强大这里主要介绍Chrome浏览器的调试工具。 打开 Google Chrome 浏览器&#xff0c…

Taro多行文本最多展示5行,超出“查看更多”展示,点击弹层

Taro中&#xff0c;页面需求&#xff1a; 多行文本&#xff0c;展示最多展示5行&#xff0c;超出5行&#xff0c;展示“查看更多”按钮&#xff0c;点击弹层展示文本详细信息。 弹层代码就不说了&#xff0c;着重说一下怎么获取区域高度&#xff5e; 1.区域设置max-height&am…

redis的键值基本操作

设置数据 首先设置键值对 删除age&#xff0c;会得到nil&#xff0c;表示这个键已经被删除掉了 判断age键还在不在 查找所有键 查找所有以me结尾的键 删除所有键 redis的键和值都是二进制存储的&#xff0c;所以默认不支持中文。 但是&#xff0c;我们重新登录客户端&#xff…

MySQL-linux安装-万能RPM法

一、MySQL的Linux版安装 1、 CentOS7下检查MySQL依赖 1. 检查/tmp临时目录权限&#xff08;必不可少&#xff09; 由于mysql安装过程中&#xff0c;会通过mysql用户在/tmp目录下新建tmp_db文件&#xff0c;所以请给/tmp较大的权限。执行 &#xff1a; chmod -R 777 /tmp2. …

为什么mac文件拖拽不了 mac文件拖不进硬盘里 macbookpro文件无法拖进移动硬盘 Tuxera NTFS for Mac 2023绿色

如果你是一位Mac用户&#xff0c;你可能会遇到这样的问题&#xff1a;你想把Mac上的文件拖拽到其他位置&#xff0c;比如桌面、文件夹或者外接硬盘&#xff0c;但是却发现无法操作&#xff0c;这是为什么呢&#xff1f;这篇文章将为你解答为什么mac文件拖拽不了&#xff0c;以及…

非关系型数据库-----------探索 Redis高可用 与持久化

目录 一、Redis 高可用 1.1什么是高可用 1.2Redis的高可用技术 二、 Redis 持久化 2.1持久化的功能 2.2Redis 提供两种方式进行持久化 三、Redis 持久化之----------RDB 3.1触发条件 3.1.1手动触发 3.1.2自动触发 3.1.3其他自动触发机制 3.2执行流程 3.3启动时加载…

增强Java技能:使用OkHttp下载www.dianping.com信息

在这篇技术文章中&#xff0c;我们将探讨如何使用Java和OkHttp库来下载并解析www.dianping.com上的商家信息。我们的目标是获取商家名称、价格、评分和评论&#xff0c;并将这些数据存储到CSV文件中。此外&#xff0c;我们将使用爬虫代理来绕过任何潜在的IP限制&#xff0c;并实…

Linux编译器 --- gcc/g++使用

文章目录 gcc/g使用1.背景知识2.gcc如何完成2.1 预处理(进行宏替换)2.2 编译&#xff08;生成汇编&#xff09;2.3 汇编&#xff08;生成机器可识别代码&#xff09;2.4 连接&#xff08;生成可执行文件或库文件&#xff09;2.5 gcc选项 gcc/g使用 1.背景知识 预处理&#xf…

iOS开发进阶(十三):脚手架创建iOS项目

文章目录 一、前言二、xcode-select 命令三、拓展阅读 一、前言 项目初期&#xff0c;需要搭建项目基本框架&#xff0c;为此离不开辅助工具&#xff0c;即脚手架。当然&#xff0c;IDE也可以实现新建空白项目&#xff0c;但是其新建后的项目结构可能不符合预期设计&#xff0…