错误报告:WebSocket 设备连接断开处理问题

错误报告:WebSocket 设备连接断开处理问题

项目背景

  1. 设备通过自启动的客户端连接到服务器,服务器将设备的 mac_address 和设备信息存入 Redis。
  2. 前端通过 Redis 接口查看设备信息并展示。

问题描述

设备连接到服务器后,前端无法立即看到设备信息。

发现的问题

  1. 设备连接后直接关机:在设备关机的情况下,服务器未及时收到断开连接的信号。由于 TCP Keep-Alive 的机制,测试中发现需要约 45 秒才会自动触发断开连接。
  2. 设备重新开机:设备重新启动后重新连接服务器。此时服务器加速了断开连接的触发(约 28 秒),但是服务器错误地删除了 Redis 中的记录。实际上,设备的连接并没有真正断开。通过向 Redis 中重新写入相同的信息,验证了 Redis 中的设备信息并未真正丢失。

目前的处理方式

为了应对上述问题,做了以下改进:

  1. 增加了校验机制:当服务器接收到断开连接时,增加了对 Redis 中存储的设备信息的检查。
  2. 心跳机制:为了更好地管理连接,预留了一个 PingPong 心跳机制,用于检测连接的有效性。由于设备端版本原因,并不全支持 pong 回应,暂时未启用这个机制,预留了一个 heartbeat ping 的函数,但它不响应 pong,后续有需要可以进一步完善。

处理方法

disconnect 方法中增加了校验机制,以确保只有在正确的条件下删除 Redis 中的设备信息。

@staticmethod
async def disconnect(ws: WebSocket, client: AsyncRedis, mac_address: str) -> None:remote_ip, remote_port = ws.clientcurrent_client_info = await client.hget(settings.REDIS_WS_CLIENT_KEY, mac_address)current_client_info = json.loads(current_client_info)if current_client_info:logger.info(f"WS_LIFESPAN: {mac_address} 正在清除状态")# 如果没有 remote port,那么说明这个链接异常,可以直接清理current_remote_port = current_client_info.get("remote_port", remote_port)# 如果旧的 ws client port 等于现在的 port,说明存储的信息仍然是当前链接的信息,可以删除if current_remote_port == remote_port:await WsService.remove_client(client, mac_address)logger.info(f"WS_LIFESPAN: {mac_address} 清除状态完成")else:logger.info(f"WS_LIFESPAN: {mac_address} 当前连接已被新连接替代,跳过清理")else:logger.info(f"WS_LIFESPAN: {mac_address} 未在 Redis 中找到客户端记录,跳过清理")

预留的 heartbeat 如下

    async def send_heartbeat():"""心跳检测- 目前只在服务器单方面检测- 如果 ping 发送失败,则认为断线,关闭连接"""while True:await asyncio.sleep(PING_INTERVAL)try:ping_msg = {"action": "ping", "timestamp": get_current_datetime_str()}await ws.send_text(json.dumps(ping_msg))logger.info(f"WS_LIFESPAN: {mac_address} 发送ping")except Exception as e:logger.error(f"WS_LIFESPAN: {mac_address} 发送ping消息失败,连接可能已断开: {str(e)}")break# 启动心跳检测任务# heartbeat_task = asyncio.create_task(send_heartbeat())

在 client 端中预留了一个 pong 机制如下 client >= 0.2.1

async def handle_ping(ws: WebSocketClientProtocol, **params):"""处理 Ping,返回 Pong"""pong_msg = {"action": "pong"}await ws.send(json.dumps(pong_msg))

解决方案

  1. TCP Keep-Alive 设置可以考虑调整 TCP Keep-Alive 设置,以加快服务器检测到设备断开的速度,从而减少等待时间。 这会影响整个设备的 TCP Keep Alive,尽量不进行
  2. 心跳机制:进一步完善 PingPong 心跳机制,确保定时检查连接是否有效。如果检测到设备失去连接,可以更快地清除 Redis 中的记录。
  3. 断开连接的逻辑加强:在断开连接的逻辑中增加更多的校验,确保只有当设备断开并且确实不再连接时才从 Redis 中移除其信息。

总结

通过对 WebSocket 断开连接的处理逻辑进行增强,增加了对 Redis 存储的校验机制,可以有效避免由于设备重新启动时,错误地删除 Redis 中的设备信息。此外,心跳机制的加入也进一步提升了连接的管理效率。

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

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

相关文章

vscode关闭后如何恢复在远程服务器的终端程序运行界面

网上有很多种解决方案,我觉得比较好用的是screen。这里先介绍screen的安装和使用办法: 通过 conda 安装 screen是比较方便的方式,可以按照以下步骤操作: 通过 Conda 安装 screen 打开终端或命令行工具。确保你已经激活了 Conda 环…

vulnhub 靶场 —— NullByte

免责声明 本博客文章仅供教育和研究目的使用。本文中提到的所有信息和技术均基于公开来源和合法获取的知识。本文不鼓励或支持任何非法活动,包括但不限于未经授权访问计算机系统、网络或数据。 作者对于读者使用本文中的信息所导致的任何直接或间接后果不承担任何…

React 初级教程

一、React 简介 React 是由 Facebook 开发的开源 JavaScript 库,用于构建用户界面(UI)。特点: 声明式编程:通过描述 UI 应该是什么样子(而不是操作 DOM)来构建界面。组件化:将 UI 拆分为独立可复用的组件。跨平台:支持 Web(React)、移动端(React Native)、VR 等。…

使用 meshgrid函数绘制网格点坐标的原理与代码实现

使用 meshgrid 绘制网格点坐标的原理与代码实现 在 MATLAB 中,meshgrid 是一个常用函数,用于生成二维平面网格点的坐标矩阵。本文将详细介绍如何利用 meshgrid 函数生成的矩阵绘制网格点的坐标,并给出具体的代码实现和原理解析。 实现思路 …

git tag的使用方法

1.添加tag git tag 2.添加tag并添加信息 git tag -a -m “your message” 3.查看tag git tag 4.推到远端 git push origin 5.推送所有本地标签到远程仓库 git push origin --tags 6.删除tag git tag -d 7.切换到某一个tag git checkout

【STM32系列】利用MATLAB配合ARM-DSP库设计FIR数字滤波器(保姆级教程)

ps.源码放在最后面 设计IIR数字滤波器可以看这里:利用MATLAB配合ARM-DSP库设计IIR数字滤波器(保姆级教程) 前言 本篇文章将介绍如何利用MATLAB与STM32的ARM-DSP库相结合,简明易懂地实现FIR低通滤波器的设计与应用。文章重点不在…

使用mermaid画流程图

本文介绍使用mermaid画流程图,并给出几个示例。 背景 目前,除有明确格式要求的文档外,笔者一般使用markdown写文档、笔记。当文档有图片时,使用Typora等软件可实时渲染,所见即所得。但如果文档接收方没有安装相关工具…

C# ASP.NET核心特性介绍

.NET学习资料 .NET学习资料 .NET学习资料 在当今的软件开发领域中,C# ASP.NET凭借其强大的功能和丰富的特性,成为构建 Web 应用程序的重要技术之一。以下将详细介绍 C# ASP.NET的核心特性。 多语言支持 ASP.NET 支持多种语言进行开发,这使…

使用Hexo部署NexT主体网站

一.使用git提交文件 参考: 从零开始搭建个人博客(超详细) - 知乎 致谢! 第一种:本地没有 git 仓库 直接将远程仓库 clone 到本地;将文件添加并 commit 到本地仓库;将本地仓库的内容push到远程仓…

12.项目结构

后端结构 ruoyi-admin 项目启动的入口 提供了两种启动方式 1.RuoYiApplication基于springboot,内置tomcat,直接运行。 2.RuoYiServletInitializer将springboot项目打成一个war包,用外置的servlet容器来运行。 通用功能的controller 后台登录相关的、权限控制相关的、数据字…

cursor如何使用到150次以及解决cursor限制问题

cursor白嫖免费版限制问题解决以后经常遇到只使用了50次额度就被限制了,软件提示you reached your trial。 解决方法 使用cursor的老版本,因为老版本有agent和normal可以切换,通过切换通往世界的IP,重启软件或者切换点几次agent和…

mmdetection3d环境部署

安装python库 pip install torch1.9.1cu111 torchvision0.10.1cu111 torchaudio0.9.1 -f https://download.pytorch.org/whl/torch_stable.html pip install mmengine pip install mmcv-2.0.0rc4-cp38-cp38-manylinux1_x86_64.whl pip install mmdet>3.0.0,<3.1.0 cd m…

基于springboot+vue的游戏创意工坊与推广平台的设计与实现

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

25自动化考研复试面试常见核心问题真题汇总,自动化考研复试面试有哪些经典问题?自动化考研复试难不难啊?

你是不是正在为考研自动化专业的复试发愁&#xff1f;担心准备不充分、表现不好&#xff1f;别慌&#xff01;今天&#xff0c;学姐——复试面试拿下90分、成功上岸的学姐&#xff0c;来给大家分享备考秘诀。复试没那么可怕&#xff0c;只要掌握正确的方法&#xff0c;你也可以…

用Kibana实现Elasticsearch索引的增删改查:实战指南

在大数据时代&#xff0c;Elasticsearch&#xff08;简称 ES&#xff09;和 Kibana 作为强大的数据搜索与可视化工具&#xff0c;受到了众多开发者的青睐。Kibana 提供了一个直观的界面&#xff0c;可以方便地对 Elasticsearch 中的数据进行操作。本文将详细介绍如何使用 Kiban…

【HarmonyOS Next 自定义可拖拽image】

效果图&#xff1a; 代码&#xff1a; import display from "ohos.display" import { AppUtil } from "pura/harmony-utils"/*** 自定义可拖拽图标组件*/ Component export default struct DraggableImage {imageResource?: ResourceimageHeight: numbe…

从0搭建卷积神经网络(CNN)--详细教学

目录 一、卷积神经网络介绍 1、简介 经典CNN架构 2、与传统神经网络区别 3、卷积神经网络的结构 (1) 卷积层&#xff08;Convolutional Layer&#xff09; (2) 激活函数&#xff08;Activation Function&#xff09; (3) 池化层&#xff08;Pooling Layer&#xff09; …

Jmeter对图片验证码的处理

Jmeter对图片验证码的处理 在web端的登录接口经常会有图片验证码的输入&#xff0c;而且每次登录时图片验证码都是随机的&#xff1b;当通过jmeter做接口登录的时候要对图片验证码进行识别出图片中的字段&#xff0c;然后再登录接口中使用&#xff1b; 通过jmeter对图片验证码…

深入理解指针初阶:从概念到实践

一、引言 在 C 语言的学习旅程中&#xff0c;指针无疑是一座必须翻越的高峰。它强大而灵活&#xff0c;掌握指针&#xff0c;能让我们更高效地操作内存&#xff0c;编写出更优化的代码。但指针也常常让初学者望而生畏&#xff0c;觉得它复杂难懂。别担心&#xff0c;本文将用通…

【CubeMX-HAL库】STM32F407—无刷电机学习笔记

目录 简介&#xff1a; 学习资料&#xff1a; 跳转目录&#xff1a; 一、工程创建 二、板载LED 三、用户按键 四、蜂鸣器 1.完整IO控制代码 五、TFT彩屏驱动 六、ADC多通道 1.通道确认 2.CubeMX配置 ①开启对应的ADC通道 ②选择规则组通道 ③开启DMA ④开启ADC…