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

netty websockt之断连重试

断连重试有以下两点考虑:

1、连接异常,比如网络抖动导致连接失败;

2、连接过程中断开连接重试;

主要用到两个工具类:

ChannelFutureListener监听ChannelFuture..isSuccess();

ChannelInboundHandlerAdapter重写channelInactive,当连接变为不活跃,则回调该方法。

完整代码如下:

@Component
public class WebSocketClient {private Channel channel;private Bootstrap bootstrap;private URI uri;private MessageHandler messageHandler;private WebSocketClientHandler handler;private volatile AtomicInteger atomicCount = new AtomicInteger(0);public WebSocketClient initClient(String host, MessageHandler messageHandler) throws Exception {this.messageHandler = messageHandler;if (StringUtils.isEmpty(host)) {throw new RuntimeException("未配置host.");}uri = new URI(host);String scheme = uri.getScheme() == null? WssSchemeEnum.WS.getValue() : uri.getScheme();//判断是否ssl连接,如果是则设置为可信final boolean ssl = WssSchemeEnum.WSS.getValue().equalsIgnoreCase(scheme);final SslContext sslCtx;if (ssl) {sslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();} else {sslCtx = null;}EventLoopGroup group = new NioEventLoopGroup();try {bootstrap = new Bootstrap();bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {ChannelPipeline p = ch.pipeline();p.addFirst(new ChannelInboundHandlerAdapter() {@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {log.error("【{}】检测到wss断连, 第 {} 次发起重连.", exchange, atomicCount.incrementAndGet());super.channelInactive(ctx);ctx.channel().eventLoop().schedule(WebSocketClient.this::doConnect, 3000, TimeUnit.MILLISECONDS);}});if (sslCtx != null) {p.addLast(sslCtx.newHandler(ch.alloc(), uri.getHost(), getUriPort(uri)));}p.addLast(new HttpClientCodec());p.addLast(new HttpObjectAggregator(8192));p.addLast(WebSocketClientCompressionHandler.INSTANCE);handler = new WebSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders()), exchange, messageHandler);p.addLast(handler);}});} catch (Exception e) {log.error("wss创建client异常. e:", e);if (bootstrap != null) {bootstrap.config().group().shutdownGracefully();}throw new RuntimeException("初始化wss连接异常. e: " + e);}doConnect();return this;}public void doConnect() {try {ChannelFuture future = bootstrap.connect(uri.getHost(), getUriPort(uri)).sync();handler.handshakeFuture().sync();future.addListener((ChannelFutureListener) cf -> {if (future.isSuccess()) {channel = future.channel();WssManger.addChannel(exchange, channel);log.info("连接成功.");messageHandler.connectSuccessAction(future.channel());atomicCount.set(0);} else {log.error("监听断连, wss第 {} 次发起重连. ", atomicCount.incrementAndGet());future.channel().eventLoop().schedule(WebSocketClient.this::doConnect, 3000, TimeUnit.MILLISECONDS);}});}catch (Exception e) {log.error("连接异常. e:" + e);if (bootstrap != null) {log.info("wss连接异常,第 {} 次发起重连.", atomicCount.incrementAndGet());bootstrap.config().group().schedule(WebSocketClient.this::doConnect, 3000, TimeUnit.MILLISECONDS);}}}/*** 根据URI获取对应的port** @param uri uri* @return port*/private int getUriPort(URI uri) {String scheme = uri.getScheme() == null? WssSchemeEnum.WS.getValue() : uri.getScheme();if (!WssSchemeEnum.allScheme().contains(scheme)) {throw new RuntimeException("Only WS(S) is supported.");}if (uri.getPort() == -1) {if (WssSchemeEnum.WS.getValue().equalsIgnoreCase(scheme)) {return WssSchemeEnum.WS.getPort();} else if (WssSchemeEnum.WSS.getValue().equalsIgnoreCase(scheme)) {return WssSchemeEnum.WSS.getPort();} else {return -1;}} else {return uri.getPort();}}
}

相关文章:

netty websockt之断连重试

断连重试有以下两点考虑&#xff1a; 1、连接异常&#xff0c;比如网络抖动导致连接失败&#xff1b; 2、连接过程中断开连接重试&#xff1b; 主要用到两个工具类&#xff1a; ChannelFutureListener监听ChannelFuture..isSuccess()&#xff1b; ChannelInboundHandlerAd…...

【Gateway】基于ruoyi-cloud-plus项目,gateway局部过滤器和过滤返回以及集成nacos

1.使用Gateway路由转发 1.1标题引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>1.2添加YML配置 spring:cloud:gateway:# 打印请求日志(自定义)…...

mysql -mmm

MMM&#xff08;Master-Master replication manager for MvSQL&#xff0c;MySQL主主复制管理器&#xff09; 是一套支持双主故障切换和双主日常管理的脚本程序。MMM 使用 Perl 语言开发&#xff0c;主要用来监控和管理 MySQL Master-Master &#xff08;双主&#xff09;复制&…...

C++初阶 类和对象(下)

目录 一、拷贝构造函数 1.1 什么是拷贝构造函数&#xff1f; 1.2 为什么得是引用&#xff1f; 1.3 使用拷贝构造函数 1.4 拷贝构造函数有什么用&#xff1f; 二、运算符重载 2.1 什么是运算符重载&#xff1f; 2.2 尝试前须知 2.3 常见运算符重载 2.3.1运算符重载 …...

使用Postman进行压力测试

1.打开Postman新建测试接口 2.点击右边保存&#xff0c;选择一个文件集合&#xff0c;如果没有就创建&#xff0c;然后保存 就是这个东西&#xff0c;这里不便展示出来&#xff0c;压力测试需要在文件夹里面进行 3.选择要测试的接口&#xff0c;iterations 表示请求发起次数&a…...

AI视频检索丨历史视频标签化,助力重要事件高效溯源

随着科技的不断发展&#xff0c;安全监控已成为我们生活中不可或缺的一部分。当发生盗窃、人员走失、安全事故等重要事件时&#xff0c;常常需要通过查看视频回放了解事情经过&#xff0c;为解决问题提供证据或指明查找方向。但是&#xff0c;人工查看视频回放往往费时费力&…...

【前段基础入门之】=>CSS3新特性 响应式布局

文章目录 概念媒体查询媒体类型媒体特性媒体运算符 概念 所谓对响应式布局方案的理解&#xff0c;众说纷纭&#xff0c;核心点就是同一套代码在不同尺度屏幕下的布局呈现方式的不同 社区中有很多人分享&#xff0c;并列出了多种实现响应式布局的方案&#xff0c;比如【 rem&…...

【Java 进阶篇】JQuery 遍历:发现元素的魔法之旅

欢迎来到 JQuery 的奇妙世界&#xff0c;一个充满活力和灵感的地方。在这个世界里&#xff0c;我们将一起探讨 JQuery 的遍历功能&#xff0c;这是一个让你轻松发现和操作网页元素的神奇工具。无需太多前端经验&#xff0c;只要有一颗探险的心&#xff0c;你就能在 JQuery 遍历…...

合肥数字孪生赋能工业制造,加速推进制造业数字化转型

聚焦国家战略需求和先进制造业发展方向&#xff0c;加快数字化发展战略部署&#xff0c;数字孪生、工业互联网、工业物联网已被广泛认为是工业革命的新引擎。合肥数字孪生正在推动工业制造从制造转向智造。通过数字化建模和仿真的方式&#xff0c;优化设计、生产、质量管理、供…...

Linux发展史与环境安装

Linux发展史与环境安装 一、Linux发展史推动技术进步的基本模式理解操作系统的发展理解Linux操作系统的发展 一、Linux的环境安装 一、Linux发展史 Linux和window XX其实都是一样的&#xff0c;定位&#xff1a;操作系统&#xff0c;企业内部&#xff0c;要给用户提供“互联网…...

【uniapp】 video视频层级、遮挡其他弹窗或顶部导航 使用nvue覆盖

uniapp 顶部导航和弹窗被video遮挡解决办法 第一步&#xff1a;配置 subNVues {"path": "pages/index/index","style": {"navigationBarTitleText": "uni-app","navigationStyle": "custom","app-…...

opencv(1):创建和显示窗口, 读取保存图片

下载源码&#xff0c;方便查看 API 信息。 快速在源码文件夹中搜索相关 api. grep“namedWindow(*-Rn// 限定 .h 文件 grep“namedWindow(*-Rn|grep "\.h" vscode 语法检测有问题 一直有波浪线 打开 vscode, setting 界面&#xff0c;搜索 python 在 setting.json…...

LeetCode530. Minimum Absolute Difference in BST

文章目录 一、题目二、题解 一、题目 Given the root of a Binary Search Tree (BST), return the minimum absolute difference between the values of any two different nodes in the tree. Example 1: Input: root [4,2,6,1,3] Output: 1 Example 2: Input: root [1,…...

Flink(五)【DataStream 转换算子(上)】

前言 这节注定是一个大的章节&#xff0c;我预估一下得两三天&#xff0c;涉及到的一些东西不懂就重新学&#xff0c;比如 Lambda 表达式&#xff0c;我只知道 Scala 中很方便&#xff0c;但在 Java 中有点发怵了&#xff1b;一个接口能不能 new 来构造对象? 答案是可以的&…...

【vitis】 AIE basic

AIE vs AIE-ML versal 期间分类 文件 操作 vitis -new -w . 安装...

微信抽奖活动怎么做

微信抽奖活动&#xff1a;打破传统&#xff0c;创新互动&#xff0c;带给你超乎想象的惊喜体验&#xff01; 随着互联网的飞速发展&#xff0c;人们越来越热衷于参与各种线上活动。而微信&#xff0c;作为中国最大的社交平台之一&#xff0c;自然成为了各种活动的聚集地。今天…...

装机必备!这5款免费软件,你值得拥有!

​ 目前win7渐渐退出视野&#xff0c;大部分人都开始使用win10了&#xff0c;笔者在日常的工作和使用中&#xff0c;为了能够让效率的大提升&#xff0c;下载了不少软件&#xff0c;以下的软件都是个人认为装机必备&#xff0c;而且都是可以免费下载。 1.屏幕亮度调节——Twin…...

华为eNSP综合实验考试

VLAN信息表 设备名称 端口 链路类型 VLAN 参数 HZ-HZCampus-Agg01-S5731 GE0/0/1 Trunk PVID:1 Allow-pass&#xff1a;10 20 Eth-trunk1&#xff08;GE0/0/2,0/0/3,0/0/23&#xff09; Trunk PVID:1 Allow-pass&#xff1a;10 20 GE0/0/24 Access PVID&#xf…...

OPPO Watch纯手机开启远程ADB调试

Wear OS手表中&#xff0c;我们可以直接在开发者设置中打开WiFi调试。但是这在OPPO等魔改Android系统中不再奏效。 需要什么&#xff1f;&#xff1f; 手表一台手机一个OTG转接头一个手表充电器一个 演示设备 手机&#xff1a; OPPO Find X手表&#xff1a; OPPO Watch 1代 …...

idea查看UML类图

idea查看UML类图 一、如何查看UML类图 1.1 选择需要查看的类或者包&#xff0c;鼠标右键&#xff0c;选择Diagrams->Show Diagram 1.2 对于UML类图中的包&#xff0c;选中后点击鼠标右键-> Expand Nodes(展开节点) 展开前 展开后 1.3 展开后分布比较凌乱&#xff…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

FFmpeg:Windows系统小白安装及其使用

一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】&#xff0c;注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录&#xff08;即exe所在文件夹&#xff09;加入系统变量…...