当前位置: 首页 > news >正文

错误报告: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 中的设备信息。此外,心跳机制的加入也进一步提升了连接的管理效率。

相关文章:

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

错误报告:WebSocket 设备连接断开处理问题 项目背景 设备通过自启动的客户端连接到服务器,服务器将设备的 mac_address 和设备信息存入 Redis。前端通过 Redis 接口查看设备信息并展示。 问题描述 设备连接到服务器后,前端无法立即看到设…...

点云配准网络

【论文笔记】点云配准网络 PCRNet: Point Cloud Registration Network using PointNet Encoding 2019_pcr-net-CSDN博客 【点云配准】【深度学习】Windows11下PCRNet代码Pytorch实现与源码讲解-CSDN博客 【点云配准】【深度学习】Windows11下GCNet代码Pytorch实现与源码讲解_…...

黑马Redis详细笔记(实战篇---短信登录)

目录 一.短信登录 1.1 导入项目 1.2 Session 实现短信登录 1.3 集群的 Session 共享问题 1.4 基于 Redis 实现共享 Session 登录 一.短信登录 1.1 导入项目 数据库准备 -- 创建用户表 CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,phone …...

51单片机俄罗斯方块整行消除函数

/************************************************************************************************************** * 名称:flash * 功能:行清除动画 * 参数:NULL * 返回:NULL * 备注: * 采用非阻塞延时&#xff0…...

Vue 3 30天精进之旅:Day 21 - 项目实践:打造功能完备的Todo应用

前言 经过前20天的学习,我们已经掌握了Vue 3的核心概念、组合式API、路由、状态管理等关键技术。今天将通过一个完整的项目实践——Todo应用,将所学知识融会贯通。我们将为Todo应用添加编辑、删除、过滤等进阶功能,并优化代码结构。 一、项目…...

32单片机学习记录1之GPIO

32单片机学习记录1之GPIO 前置 GPIO口在单片机中扮演着什么角色? 在单片机中,GPIO口(General Purpose Input/Output) 是一种通用输入/输出接口,扮演着连接单片机与外部设备的桥梁角色。具体来说,它在单片…...

AI 编程助手 Cline

Cline 是一款集成于 Visual Studio Code(VS Code)的 AI 编程助手,旨在提升开发者的编程效率和代码质量。 主要功能: 代码生成与补全:Cline 能根据开发者的输入,自动生成代码片段或完整的函数,减…...

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-patches.py

patches.py ultralytics\utils\patches.py 目录 patches.py 1.所需的库和模块 2.def imread(filename: str, flags: int cv2.IMREAD_COLOR): 3.def imwrite(filename: str, img: np.ndarray, paramsNone): 4.def imshow(winname: str, mat: np.ndarray): 5.PyTorch…...

R语言LCMM多维度潜在类别模型流行病学研究:LCA、MM方法分析纵向数据

全文代码数据:https://tecdat.cn/?p39710 在数据分析领域,当我们面对一组数据时,通常会有已知的分组情况,比如不同的治疗组、性别组或种族组等(点击文末“阅读原文”获取完整代码数据)。 然而,…...

2025 年前端开发现状分析:卷疯了还是卷麻了?

一、前端现状:框架狂飙,开发者崩溃 如果你是个前端开发者,那么你大概率经历过这些场景: 早上打开 CSDN(或者掘金,随便),发现又有新框架发布了,名字可能是 VueXNext.js 之…...

RDK新一代模型转换可视化工具!!!

作者:SkyXZ CSDN:SkyXZ~-CSDN博客 博客园:SkyXZ - 博客园 之前在使用的RDK X3的时候,吴诺老师wunuo发布了新一代量化转换工具链使用教程,这个工具真的非常的方便,能非常快速的完成X3上模型的量化…...

JVM春招快速学习指南

1.说在前面 在Java相关岗位的春/秋招面试过程中,JVM的学习是必不可少的。本文主要是通过《深入理解Java虚拟机》第三版来介绍JVM的学习路线和方法,并对没有过JVM基础的给出阅读和学习建议,尽可能更加快速高效的进行JVM的学习与秋招面试的备战…...

C#中的序列化和反序列化

序列化是指将对象转换为可存储或传输的格式,例如将对象转换为JSON字符串或字节流。反序列化则是将存储或传输的数据转换回对象的过程。这两个过程在数据持久化、数据交换以及与外部系统的通信中非常常见 把对象转换成josn字符串格式 这个过程就是序列化 josn字符…...

xcode常见设置

1、如何使用cmake构建archs为$(ARCHS_STANDARD)的xcode项目 在cmake中使用如下指令 set(CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD)") cmake - nomadli的博客 | nomadli Blog...

PG高可用学习@2

目录标题 一、Patroni 支持在同步复制下备库故障时自动降级为异步复制?参考依据1. PostgreSQL 官方文档2. Patroni 官方文档3. 高可用和容错设计原则 二、patroni 是如何检测备库故障的?1. 心跳机制2. 监控数据库进程状态3. 查询系统视图4. 复制延迟监测5. 网络连接…...

centos 8和centos 9 stream x64的区别

以下是 CentOS 8 与 CentOS Stream 9 的主要区别,从技术架构、更新策略到适用场景等维度进行对比: AI产品独立开发实战营 联系我了解 1. 定位与更新策略 特性CentOS 8CentOS Stream 9定位原为 RHEL 8 的免费稳定复刻版RHEL 9 的上游开发分支&#xff…...

C++基础学习记录—类

1、面向对象的三大特征:封装、继承、多态 2、类和对象 2.1、类的概念 类:类是一个抽象的概念,用于描述同一类对象的特点。 对象:根据类的概念所创造的实体。 类中包含属性和行为 属性:描述类的数据,一…...

云原生时代的后端开发:架构、工具与最佳实践

随着云计算的迅猛发展,云原生(Cloud Native)逐渐成为后端开发的主流趋势。云原生后端不仅能够提高应用的灵活性和可扩展性,还能显著优化开发和运维流程。本文将围绕云原生后端的关键概念、当前热门技术及最佳实践,帮助…...

ARM Cortex-M3/M4 权威指南 笔记【一】技术综述

一、Cortex-M3/M4 处理器的一般信息 1.1 处理器类型 ARM Cortex-M 为 32 位 RISC(精简指令集)处理器,其具有: 32位寄存器32位内部数据通路32位总线接口 除了 32 位数据,Cortex-M 处理器(以及其他任何 A…...

12.项目结构

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

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)

在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...