记一次netty客户端的开发
背景
近日要开发一个tcp客户端程序去对接上游厂商的数据源,决定使用netty去处理,由于很久没有开发过netty了,顺便学习记录下
netty搭建
考虑到我们需要多个client去对接server服务,所以我们定义一个公共的AbstractNettyClient父类,定义一些公共的方法,比如,连接,重试等。以达到代码复用
我这里采用的是三层结构的设计,因为对接的上游数据厂商的不止一家,每家厂商会存在一定的定制化逻辑,所以在此进行封装
- 公共的nettyClient父类,所有netty 子类继承
- 具体上游厂商的父类,实现厂商对接的一些公共处理
- 真正实现的子类,有多少个需要对接的,就实现多少
需要哪些公共方法
对于最上层的netty,我们应该定义有哪些全局的公共方法,这里给出几个通用示例
public void start(){// 启动操作
}public void stop(){// 停止操作
}public void restart(){// 重启操作
}
需要哪些Handler?
了解过netty基础的都知道,netty中有inbound和outbound两个出入站的链路处理器供我们处理接受与发送的消息,那么作为全局公共的父类,自然要提供给子类可扩展的handler自选,同时也要维护全局公共的handler,那么这里定义一个公共模板的handler获取方法
public ChannelInitializer getChannelHandler(AbstractNettyConnector connector) {return new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline();pipeline.addLast(new ReadTimeoutHandler(15, TimeUnit.SECONDS));pipeline.addLast(new LoggingHandler());addPipeline(pipeline);}};}public void addPipeline(){// 子类覆盖时间该方法
}
通过这样的方式我们在定义公共的handler同时也能支持子类实现自定义的handler处理特定的事件。
下边给出一些常见的通用handler
- ReconnectHandler:重连处理,我们在连接服务端,可能由于网络或者其他问题,会导致连接断开,这个时候我们就需要一个handler去处理重连的情况
- ReadTimeoutHandler:因为客户端只做读取,所以这边还需要一个超时读取的handler,用于检测服务读取通道的状态,如果超时未读取数据,那么我们可以做一些操作
- DecodeHandler:解码器,在处理真正的消息之前我们需要先解码数据
- MessageHandler:消息处理器,解析完解码的数据后,我们真正对消息进行处理的地方
我们整个通用链路的handler,大概就如下
解码器的选择
由于TCP连接中存在粘包黏包的现象,发过来的消息不一定是个完整的包,所以我们在我们自己的解码器之前还需要定一个解码器处理粘包黏包的问题,对于我自己这边使用的是,定长的解码器
new LengthFieldBasedFrameDecoder(ByteOrder.LITTLE_ENDIAN, 1500, 0, 2, -2, 0, true)
对于该解码器构造参数的解析
- 大端和小端模式的选择,这个需要具体询问上游的消息格式
- 定长长度
- lengthFieldOffset:表示这个包长度的字段,是从第几个字节开始读
- lengthFieldLength:长度字段所占用的字节数
- lengthAdjustment:用来修正长度字段,比如说你的长度读出来的字节数,并不包含自己,那么在该值里 你就得填这个长度字段的长度
举例:假设现在有个2个字节的长度字段,读出来的值是152,这个值是数据包的长度不包含长度字段,那么lengthAdjustment就应该填-2,减去长度字段 得到真正的数据长度
连接监听器
在启动netty客户端时,可能会产生连接失败等情况,这个时候我们可以在启动处增加一个连接监听器,用来监控启动情况,这个不同于ReconnectHandler,那个是用于处理连接建立和断开时的重连器
ChannelFuture connect = bootstrap.connect(serverAddress, serverPort);
connect.addListener(new ConnectListener(this));public class ConnectListener implements ChannelFutureListener {@Overridepublic void operationComplete(ChannelFuture future) throws Exception {if (!future.isSuccess()) {Throwable cause = future.cause();if (cause instanceof ConnectTimeoutException) {// do something} else {log.error("连接异常", cause);}future.channel().close();}}
相关文章:

记一次netty客户端的开发
背景 近日要开发一个tcp客户端程序去对接上游厂商的数据源,决定使用netty去处理,由于很久没有开发过netty了,顺便学习记录下 netty搭建 考虑到我们需要多个client去对接server服务,所以我们定义一个公共的AbstractNettyClient父…...
策略模式结合Spring使用
1.抽象策略 /*** 支付方式策略* author Linging* version 1.0.0* since 1.0*/ public interface PayStrategy {void pay(BigDecimal money);}2.具体策略 /*** 支付宝* author Linging* version 1.0.0* since 1.0*/ Component("aliPayStrategy") public class AliPa…...

基于 RNNs 对 IMDB 电影评论进行情感分类
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对抗网络、门控循环单元、长短期记…...

Midjourney绘画参数设置详解
在数字艺术和设计领域,Midjourney是一款强大的绘画工具,它允许艺术家和设计师以数字方式创作出精美的图像。为了充分发挥Midjourney的潜力,正确设置其绘画参数至关重要。本文将深入探讨Midjourney的绘画参数设置,帮助用户更好地掌…...

计算机毕业设计 | springboot养老院管理系统 老人社区管理(附源码)
1,绪论 1.1 背景调研 养老院是集医疗、护理、康复、膳食、社工等服务服务于一体的综合行养老院,经过我们前期的调查,院方大部分工作采用手工操作方式,会带来工作效率过低,运营成本过大的问题。 院方可用合理的较少投入取得更好…...
事务与并发控制
事务(Transaction0):要么全做,要么全不做; 事务ACID:原子性Atomicity;一致性Consistency;隔离性Isolation;持久性Durability; 并发操作问题: 1.…...

spring boot 中的异步@Async
spring boot 开启异步调用 1、启动类上添加EnableAsync注解,表示启动异步 2、在具体实现异步的方法上添加Async注解 package com.example.demo;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootAppli…...

【C++/STL】list(常见接口、模拟实现、反向迭代器)
🌈个人主页:秦jh_-CSDN博客🔥 系列专栏:https://blog.csdn.net/qinjh_/category_12575764.html?spm1001.2014.3001.5482 目录 前言 list的常见接口 对迭代器的封装 节点 重载-> const迭代器 list与vector的对比 反向迭代…...

wms中对屏幕进行修改wm size设置屏幕宽高原理剖析
背景: 上面是正常屏幕1440x2960的屏幕大小,如果对display进行相关的修改,可以使用如下命令: adb shell wm size 1080x1920 得出如下的画面 明显看到差异就是屏幕上下有黑边了,那么下面就来调研这个wm size是怎么做的…...
java面试题及答案2024,java2024最新面试题及答案(之一)
发现网上很多Java面试题都没有答案,所以花了很长时间搜集整理出来了这套Java面试题大全,希望对大家有帮助哈~ 本套Java面试题大全,全的不能再全,哈哈~ 一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Ja…...

Go Modules 使用
文章参考https://blog.csdn.net/wohu1104/article/details/110505489 不使用Go Modules,所有的依赖包都是存放在 GOPATH /pkg下,没有版本控制。如果 package 没有做到完全的向前兼容,会导致多个项目无法运行(包版本需求不同)。 于是推出了g…...

结账和反结账
结账与反结账功能在财务软件和会计系统中扮演着重要的角色,以下是关于这两个功能的详细解释: 一、结账功能 结账功能是计算和结转各个会计科目本期发生额和期末余额的过程,同时标志着一定时期内财务活动的结束和财务数据的固化。结账功能的…...

k8s怎么监听资源的变更
监听k8s所有的 Deployment 资源 package mainimport ("context""fmt"v1 "k8s.io/api/apps/v1""k8s.io/apimachinery/pkg/util/json""k8s.io/client-go/informers""k8s.io/client-go/kubernetes""k8s.io/cli…...

Cobaltstrike常用功能
一、快捷工具栏 3、需要创建监听器,才能让靶机上线,连接我们公网服务端上去开启的帧监听端口,做任何操作 都是通过服务器的IP地址去连接靶机,去和靶机进行文件stage的一个传输和交互。这里推荐把cs 放到公网上边,比较…...
UWP与WPF:微软两大UI框架
在微软的开发者生态系统中,UWP(Universal Windows Platform)与WPF(Windows Presentation Foundation)是构建Windows应用的两大明星框架。它们各自携带独特的设计理念和技术特性,服务于不同的开发需求和应用场景。本文将深入探讨这两者之间的异同…...
【面试】字节码文件是跨平台的吗?
目录 1. 说明 1. 说明 1.字节码文件(.class文件)是跨平台的。2.字节码文件是Java源代码经过Java编译器(javac)编译后生成的中间代码文件,这些包含了Java虚拟机(JVM)指令,而不是特定…...

SpringCloud中注册中心Nacos的下载与使用步骤
1.前言 Nacos(Dynamic Naming and Configuration Service)是阿里巴巴开源的一款服务发现和配置管理工具。它可以帮助用户自动化地进行服务注册、发现和配置管理,是面向微服务架构的一个重要组成部分。 2.下载 链接:https://pan.b…...

心缘Hub小程序
心缘Hub小程序 文章目录 心缘Hub小程序[TOC](文章目录) 前言飞书文章:[添加链接描述](https://mqdyd6qj756.feishu.cn/wiki/X9qbwrq70i43W0kr5X8cqytSnKb) 一、简介 前言 飞书文章:添加链接描述 一、简介 心缘Hub 不要钱可以匹配 有缘人 、直接拿微信…...

攻防世界maze做法(迷宫题)
首先查壳64bit,直接丢进ida64中进行反编译就完事儿了,然后直接进入main函数打注释分析首先,题目已经提示了这是个迷宫题,我们抓住做迷宫题的两个要点,一找玩法,二找地图, 玩法在主函数中&#…...
PID——调参的步骤
第一步:确定比例增益P 确定比例增益 P 时,首先去掉 PID 的积分项和微分项,一般是令 Ti0、 Td0(具体见PID 的参数设定说明),使PID 为纯比例调节。 输入设定为系统允许的最大值60%~70%,由0逐渐加…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...