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

java-netty客户端断线重启

背景

经常会遇到netty客户端,因为网络等多种原因而断线,需要自动重连

核心

就是对连接服务端成功后,对ChannelFuture进行监听,核心代码如下

            f = b.connect("127.0.0.1", 10004).sync(); // (5)f.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture channelFuture) throws Exception {if(!channelFuture.isSuccess()){System.out.println("重试");channelFuture.channel().eventLoop().schedule(new Runnable() {@Overridepublic void run() {doReconnect();}},3,TimeUnit.SECONDS);}else{}}});

具体代码

nettyClient

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import java.util.Random;
import java.util.concurrent.TimeUnit;public class nettyClient {private static ChannelFuture f;static EventLoopGroup workerGroup;static Bootstrap b;static ChannelFutureListener channelFutureListener=null;static NettyClientHandlerInner nettyClientHandlerInner = new NettyClientHandlerInner();public static void main(String[] args) throws Exception {new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {Thread.sleep(2000);nettyClientHandlerInner.sendMSG("writeWumingStatus@@" + new Random().nextInt(20000));Thread.sleep(2000);nettyClientHandlerInner.sendMSG("writePazhanfoStatus@@" + new Random().nextInt(20000));nettyClientHandlerInner.sendMSG("pkRecord@@" + new Random().nextInt(20000));} catch (InterruptedException e) {e.printStackTrace();}}}}).start();init();connectToServer(nettyClientHandlerInner);}public static void init() {workerGroup = new NioEventLoopGroup();b = new Bootstrap(); // (1)b.group(workerGroup); // (2)b.channel(NioSocketChannel.class); // (3)b.option(ChannelOption.SO_KEEPALIVE, true); // (4)b.handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new LineBasedFrameDecoder(1024));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(nettyClientHandlerInner);}});channelFutureListener=new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture channelFuture) throws Exception {if(!channelFuture.isSuccess()){channelFuture.channel().eventLoop().schedule(new Runnable() {@Overridepublic void run() {doReconnect();}},3,TimeUnit.SECONDS);}else{System.out.println("重连成功");}}};}public static void connectToServer(NettyClientHandlerInner nettyClientHandler) {try {// Start the client.f = b.connect("127.0.0.1", 10004).sync(); // (5)f.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture channelFuture) throws Exception {if(!channelFuture.isSuccess()){System.out.println("重试");channelFuture.channel().eventLoop().schedule(new Runnable() {@Overridepublic void run() {doReconnect();}},3,TimeUnit.SECONDS);}else{}}});// Wait until the connection is closed.f.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();}}public static void doReconnect(){ChannelFuture future=b.connect("127.0.0.1", 10004);future.addListener(channelFutureListener);}
}

NettyClientHandlerInner

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;import java.io.IOException;
import java.util.concurrent.TimeUnit;@ChannelHandler.Sharable
class NettyClientHandlerInner extends ChannelInboundHandlerAdapter {ChannelHandlerContext ctxOut;//通道就绪事件(就是在bootstrap启动助手配置中addlast了handler之后就会触发此事件)//但我觉得也可能是当有客户端连接上后才为一次通道就绪public void channelActive(ChannelHandlerContext ctx) throws IOException, InterruptedException {System.out.println("客户端消息,通道激活,可以发送消息了");ctxOut=ctx;}//数据读取事件public void channelRead(ChannelHandlerContext ctx, Object msg) {//传来的消息包装成字节缓冲区String byteBuf = (String) msg;
//        ByteBuf byteBuf = (ByteBuf) msg;//Netty提供了字节缓冲区的toString方法,并且可以设置参数为编码格式:CharsetUtil.UTF_8System.out.println("客户端读取服务返回的数据:" + byteBuf);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)// Close the connection when an exception is raised.cause.printStackTrace();System.out.println(cause.getMessage());ctx.close();}public void  sendMSG(String msg){ctxOut.writeAndFlush(Unpooled.copiedBuffer(msg+"\r\n", CharsetUtil.UTF_8));}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {super.channelInactive(ctx);System.out.println("与服务器断开");ctx.channel().eventLoop().schedule(new Runnable() {@Overridepublic void run() {nettyClient.doReconnect();}}, 3, TimeUnit.SECONDS);ctx.close();}
}

总结

要实现重连,有三个地方需要注意

  1. 对连接成功的ChannelFuture进行监听,调用doReconnect
  2. 实现如上的doReconnect
  3. 在NettyClientHandlerInner中重写channelInactive,再次调用doReconnect
    @Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {super.channelInactive(ctx);System.out.println("与服务器断开");ctx.channel().eventLoop().schedule(new Runnable() {@Overridepublic void run() {nettyClient.doReconnect();}}, 3, TimeUnit.SECONDS);ctx.close();}

相关文章:

java-netty客户端断线重启

背景 经常会遇到netty客户端&#xff0c;因为网络等多种原因而断线&#xff0c;需要自动重连 核心 就是对连接服务端成功后&#xff0c;对ChannelFuture进行监听&#xff0c;核心代码如下 f b.connect("127.0.0.1", 10004).sync(); // (5)f.addListener(new Chan…...

MySQL的基础用法一

数据库的操作 对库的操作 SQL通用语法规则介绍 创建数据库 使用数据库 查询所有数据库 查询当前数据库 删除数据库 对库中表的操作 创建一个表 查询当前数据库所有表 查询表结构 查询指定表的建表语句 &#x1f698;&#x1f698;&#x1f698;正片开始 SQL通用语…...

Linux:进程地址空间

目录 一、虚拟地址 二、进程地址空间 一、虚拟地址 父进程和子进程之间&#xff0c;代码共享&#xff0c;而数据可能会发生修改&#xff0c;所以当其中一个进程要写入数据时&#xff0c;则发生写时拷贝&#xff0c;各自私有一份。 现在有源文件内容如下所示。 int glob_val …...

数据结构:树、森林

二叉树与树结构差异 树&#xff08;一般树&#xff09;&#xff1a;树是一种数据结构&#xff0c;其中每个节点可以有任意数量的子节点&#xff08;除了根节点和叶子节点外&#xff09;。因此&#xff0c;一般树的节点在数组中的表示并不是那么直接&#xff0c;特别是当树不是完…...

AI Agent应用出路到底在哪?

1 Agent/Function Call 的定义 Overview of a LLM-powered autonomous agent system&#xff1a; Agent学会调用外部应用程序接口&#xff0c;以获取模型权重中缺失的额外信息&#xff08;预训练后通常难以更改&#xff09;&#xff0c;包括当前信息、代码执行能力、专有信息源…...

一文了解构建工具——Maven与Gradle的区别

目录 一、Maven和Gradle是什么&#xff1f; 构建工具介绍 Maven介绍 Gradle介绍 二、使用时的区别&#xff1a; 1、新建项目 Maven&#xff1a; Gradle&#xff1a; 2、配置项目 Maven&#xff1a; Gradle&#xff1a; 3、构建项目——生成项目的jar包 Gradle&…...

electron介绍

Electron中文文档 Electron是什么&#xff1f; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 允许开发者使用前端技术栈来创建可以在 Windows、macOS 和 Linux 等多个操作系统上运行的桌面应用程序。 Electron 本质上是一个运行在桌面操作…...

Redis-持久化

首先,我们明白一个概念, 硬盘>持久 内存>不持久 而Redis是一个内存数据库,不持久,相比于Mysql这样的关系型数据库,最明显的特点是快/效率高 为了保证速度快,数据要保存再内存中,为了持久,存储在硬盘上 所以redis决定: 插入>内存&#xff0b;硬盘(硬盘是为了在re…...

封装轮播图 (因为基于微博小程序,语法可能有些出入,如需使用需改标签)

这是在组件中使用&#xff0c;基于微博语法 <template><wbx-view class"" style"width: 100vw;height: 70vh;"><WBXswiper change"gaibian" :vertical"false" :current"current" indicatorActiveColor"…...

【Ubuntu】minicom安装、配置、使用以及退出

目录 1 安装 2 配置 3 使用 4 退出 minicom是一个串口通信的工具&#xff0c;以root权限登录系统&#xff0c;可用来与串口设备通信。 1 安装 sudo apt-get install minicom 2 配置 使用如下命令进入配置界面&#xff1a; sudo minicon -s 进入配置界面后&#xff0c;…...

MYSQL的监控

1. MySQL服务器都提供了哪几种类型的日志文件&#xff1f;说明每种日志的用途。 Error log&#xff1a;启动、关闭和异常有关的诊断信息 General query log:服务器从客户端收到的所有语句 Slow query log:需要很长时间执行的查询 Audit log:企业版基于策略的审计 Binary…...

CTF ciscn_2019_web_northern_china_day1_web2

ciscn_2019_web_northern_china_day1_web2 BEGIN 拿到题目&#xff0c;先看看 这里发现一个很像提示的东西&#xff0c;然后发现下面是一堆小电视商品&#xff0c;有lv等级和金钱&#xff0c;所以这题的入口可能就是再lv6和这个资金募集上 然后点击下next&#xff0c;看看页…...

linux中vim编辑器的应用实例

前言 Linux有大量的配置文件&#xff0c;其中编辑一些配置文件&#xff0c;最常用的工具就是 Vim &#xff0c;本文介绍一个实际应用的Vim编辑器开发文档的实例。 Vim是一个类似于Vi的著名的功能强大、高度可定制的文本编辑器&#xff0c;在Vi的基础上改进和增加了很多特性。…...

智慧城市交通管理中的云端多车调度与控制

城市交通管理中的云端多车调度与控制 智慧城市是 21世纪的城市基本发展方向&#xff0c;为了实现智慧城市建设的目标&#xff0c;人们需要用现代化的手段去管理和控制城市中的各种资源和设施。智能交通控制与管理是智慧城市中不可缺少的一部分&#xff0c;因为现代城市交通系统…...

分治(归并排序)

一、基本思路 我们以一个归并排序为例。 . - 力扣&#xff08;LeetCode&#xff09; 归并排序的思想&#xff1a;得到两个有序数组&#xff0c;把两个有序数组合并&#xff0c;传到下一层递归&#xff0c;一直得到两个有序数组&#xff0c;一直合并&#xff0c;最后就能得到有…...

小学生为什么要学英语

小学生需要学习英语的原因有很多&#xff0c;以下是其中的一些原因&#xff08;毕竟我也会累滴(*&#xffe3;▽&#xffe3;*)&#xff09;&#xff1a; 1. 全球化交流&#xff1a;英语是国际交流的通用语言&#xff0c;学习英语可以帮助小学生更好地融入全球化的社会环境&am…...

企业云存储如何收费?企业云存储收费标准

企业云存储如何收费&#xff1f;企业云存储的收费方式因不同的服务提供商和具体的服务选项而异&#xff0c;通常从用户数量、存储容量、功能、混合收费、按需定价、定制化、功能模块等多个方面进行考量。以下是对其多方面收费方式的详细介绍&#xff1a; 1.按用户数量收费 适用…...

一步步教你LangGraph Studio:可视化调试基于LangGraph构建的AI智能体

之前我们在第一时间介绍过使用LangChain的LangGraph开发复杂的RAG或者Agent应用&#xff0c;随着版本的迭代&#xff0c;LangGraph已经成为可以独立于LangChain核心&#xff0c;用于开发多步骤、面向复杂任务、支持循环的AI智能体的强大框架。 近期LangGraph推出了一个使得复杂…...

用SpringBoot打造先进的学科竞赛管理系统

1绪 论 1.1研究背景 当今时代是飞速发展的信息时代。在各行各业中离不开信息处理&#xff0c;这正是计算机被广泛应用于信息管理系统的环境。计算机的最大好处在于利用它能够进行信息管理。使用计算机进行信息控制&#xff0c;不仅提高了工作效率&#xff0c;而且大大的提高了其…...

Linux入门攻坚——34、nsswitch、pam、rsyslog和loganalyzer前端展示工具

nsswitch&#xff1a;network service switch 名称解析&#xff1a;name <---> id 认证服务&#xff1a;用户名、密码验证或token验证等 名称解析和认证服务都涉及查找位置&#xff0c;即保存在哪里。如linux认证&#xff0c;passwd、shadow&#xff0c;是在文件中&…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...