Netty常用核心类说明
MessageToByteEncoder
MessageToByteEncoder是一个抽象编码器,子类可重写encode方法把对象编码为ByteBuf输出。
MessageToByteEncoder继承自ChannelOutboundHandlerAdapter,encode在出站是被调用。
public class MyMessageEncoder extends MessageToByteEncoder<MessagePO> {@Overrideprotected void encode(ChannelHandlerContext ctx, MessagePO msg, ByteBuf out) throws Exception {System.out.println("MyMessageEncoder.encode,被调用");String json = JSONObject.toJSONString(msg);out.writeInt(json.getBytes(StandardCharsets.UTF_8).length);out.writeBytes(json.getBytes(StandardCharsets.UTF_8));}
}
ByteToMessageDecoder
ByteToMessageDecoder是一种ChannelInboundHandler,可以称为解码器,负责将byte字节流(ByteBuf)转换成一种Message,Message是应用可以自己定义的一种Java对象。
ByteToMessageDecoder:用于将字节转为消息,需要检测缓冲区是否有足够的字节。
public class MyMessageDecoder extends ByteToMessageDecoder {@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {System.out.println("MyMessageDecoder.decode,被调用");while (in.readableBytes() >= 4){int num = in.readInt();System.out.println("解码出一个整数:"+num);out.add(num);}}
}
ReplayingDecoder
ReplayingDecoder:继承自ByteToMessageDecoder,不需要检测缓冲区是否有足够的字节,但是ReplayingDecoder的速度略慢于ByteToMessageDecoder,而且并不是所有的ByteBuf都支持。
项目复杂度高用ReplayingDecoder,否则使用ByteToMessageDecoder。
public class MyMessageDecoder extends ReplayingDecoder<Void> {@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {System.out.println("MyMessageDecoder.decode,被调用");int length = in.readInt();byte[] content = new byte[length];in.readBytes(content);String json = new String(content,StandardCharsets.UTF_8);MessagePO po = JSONObject.parseObject(json,MessagePO.class);out.add(po);}
}
MessageToMessageEncoder
用于从一种消息编码为另外一种消息,例如从POJO到POJO,是一种ChannelOutboundHandler
MessageToMessageDecoder
从一种消息解码为另一种消息,例如POJO到POJO,是一种ChannelInboundHandler
MessageToMessageCodec
整合了MessageToMessageEncoder 和 MessageToMessageDecoder
public class RequestMessageCodec extends MessageToMessageCodec<String, RequestData> {@Overrideprotected void encode(ChannelHandlerContext ctx, RequestData msg, List<Object> out) throws Exception {System.out.println("RequestMessageCodec.encode 被调用 " + msg);String json = JSONObject.toJSONString(msg);out.add(json);}@Overrideprotected void decode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception {System.out.println("RequestMessageCodec.decode 被调用 " + msg);RequestData po = JSONObject.parseObject(msg, RequestData.class);out.add(po);}
}
ChannelInitializer
ChannelInitializer是一种特殊的ChannelInboundHandler,可以通过一种简单的方式(调用initChannel方法)来初始化Channel。
通常在Bootstrap.handler(ChannelHandler) , ServerBootstrap.handler(ChannelHandler) 和 ServerBootstrap.childHandler(ChannelHandler)中给Channel设置ChannelPipeline。
注意:当initChannel被执行完后,会将当前的handler从Pipeline中移除。
Bootstrap bootstrap = new Bootstrap().group(group)//设置线程组.channel(NioSocketChannel.class)//设置客户端通道的实现类.handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new NettyClientHandler());//加入自己的处理器}});
ServerBootstrap bootstrap = new ServerBootstrap().group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)//使用NioServerSocketChannel作为服务器的通道实现.option(ChannelOption.SO_BACKLOG, 128)//设置线程队列等待连接的个数.childOption(ChannelOption.SO_KEEPALIVE, true)//设置保持活动连接状态
// .handler(null)//该Handler对应bossGroup.childHandler(new ChannelInitializer<SocketChannel>() {//给workerGroup的EventLoop对应的管道设置处理器@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new NettyServerHandler());}});
SimpleChannelInboundHandler
SimpleChannelInboundHandler继承自ChannelInboundHandlerAdapter,可以通过泛型来规定消息类型。
处理入站的数据我们只需要实现channelRead0方法。
SimpleChannelInboundHandler在接收到数据后会自动release掉数据占用的Bytebuffer资源,ChannelInboundHandlerAdapter不会自动释放。
public class MyClientHandler extends SimpleChannelInboundHandler<MessagePO> {@Overrideprotected void channelRead0(ChannelHandlerContext ctx, MessagePO msg) throws Exception {System.out.println("收到服务端消息:" + msg);}
}
DefaultEventLoopGroup
在向pipline中添加ChannelHandler时,可以提供一个新的线程组,Handler业务会在该线程中执行。
当加ChannelHandler需要执行多线程并发业务时,DefaultEventLoopGroup可以派上大用处。
如果没有设置DefaultEventLoopGroup,默认使用的是EventLoopGroup workerGroup = new NioEventLoopGroup();
DefaultEventLoopGroup businessGroup = new DefaultEventLoopGroup(100);
...
addLast(businessGroup, new MyNettyServerHandler())
/*** 读取客户端发送过来的消息*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf byteBuf = (ByteBuf) msg;System.out.println("收到客户信息:" + byteBuf.toString(CharsetUtil.UTF_8));System.out.println("客户端地址:" + ctx.channel().remoteAddress());System.out.println("处理线程:" + Thread.currentThread().getName());ctx.executor().parent().execute(()->{try {System.out.println("parent().execute Thread = " + Thread.currentThread().getName());TimeUnit.SECONDS.sleep(2L);System.out.println("parent任务执行完成1");} catch (InterruptedException e) {e.printStackTrace();}});ctx.executor().parent().execute(()->{try {System.out.println("parent().execute Thread = " + Thread.currentThread().getName());TimeUnit.SECONDS.sleep(2L);System.out.println("parent任务执行完成2");} catch (InterruptedException e) {e.printStackTrace();}});ctx.executor().parent().execute(()->{try {System.out.println("parent().execute Thread = " + Thread.currentThread().getName());TimeUnit.SECONDS.sleep(2L);System.out.println("parent任务执行完成3");} catch (InterruptedException e) {e.printStackTrace();}});
}
以上代码执行日志如下:
收到客户信息:Hello 服务端
客户端地址:/127.0.0.1:60345
处理线程:defaultEventLoopGroup-4-1
parent().execute Thread = defaultEventLoopGroup-4-2
parent().execute Thread = defaultEventLoopGroup-4-3
程序继续~~ defaultEventLoopGroup-4-1
parent().execute Thread = defaultEventLoopGroup-4-4
parent任务执行完成1
parent任务执行完成3
parent任务执行完成2
EventLoop定时任务
可以在Handler中通过方法ctx.channel().eventLoop().schedule()添加定时任务
ctx.channel().eventLoop().schedule(()->{try {System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());TimeUnit.SECONDS.sleep(2L);System.out.println("定时任务执行完成");} catch (InterruptedException e) {e.printStackTrace();}
},10L,TimeUnit.SECONDS);
相关文章:
Netty常用核心类说明
MessageToByteEncoder MessageToByteEncoder是一个抽象编码器,子类可重写encode方法把对象编码为ByteBuf输出。 MessageToByteEncoder继承自ChannelOutboundHandlerAdapter,encode在出站是被调用。 public class MyMessageEncoder extends MessageToB…...
ingress服务
user.default.svc.cluster.local是集群内部service的dns地址,集群外部想访问集群里面的service,可以通过LoadBalaner和NodePort。LoadBalaner可以获得一个公网ip;NodePort在宿主机上开一个端口,访问这个端口会把报文实际的转发到集…...
java 抽象类 详解
目录 一、抽象类概述: 二、抽象方法 : 1.概述 : 2.应用 : 3.特点 : 三、抽象类特点 : 1.关于abstract关键字 : 2.抽象类不能被实例化,只能创建其子类对象 : 3.抽象类子类的两个选择 : 四、抽象类的成员 : 1.成员变量 : 2.成员方…...
MySQL的安装(详解)
文章目录前言一、yum方式安装1、下载并安装MySQL2、 启动MySQL数据库3、查看MySQL初始密码4、登录数据库5、修改MySQL默认密码6、授予root用户远程管理权限7、输入exit退出数据库二、rpm安装方式1、检查2、卸载mariadb3、安装4、启动5、密码总结前言 本教程为Linux下安装mysql的…...
界面控件DevExpress WinForm——轻松构建类Visual Studio UI(二)
DevExpress WinForm拥有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任…...
BabylonJS之放烟花
一: 技术调研 1. 方案一:ParticleSystem 用ParticleSystem来实现每一束的烟花效果,如果浏览器支持WebGL2功能,使用GPUParticleSystem性能会有极大的提升。 优点: 烟花效果易实现且效果好。 缺点: 每一个P…...
vue3 布局样式的原理
style scoped <style scoped > 它的 CSS 只作用于当前组件中的元素,如果子组件只有一个根元素,也会被渗透 原理: 当我们再组建中使用scoped时,vue会自动为组件中所有元素生成一个随机的属性,形如:da…...
Qt程序使用路径方式和注意事项
Qt程序使用路径方式和注意事项 更多精彩内容👉个人内容分类汇总 👈👉Qt开发经验 👈文章目录Qt程序使用路径方式和注意事项[toc]前言一、Windows下Qt程序使用路径1.准备工作2.测试结果二、Linux下Qt程序使用路径1.准备工作2.测试结…...
和日期相关的代码和bug——一道力扣题中的小发现
目录 Day of the Week 题目大意 常规方法 Python代码 Golang代码 C代码 基姆拉尔森公式 Python代码 Golang代码 C代码 使用库函数 Python代码 Golang代码 C代码 Day of the Week Given a date, return the corresponding day of the week for that date. The inp…...
如何在2023年学习编程并获得开发者工作
丢下自负 许多进入软件开发领域的人都是从最底层开始的,你可能会获得“初级开发者”的头衔。每天面临的问题是:我有十年的专业经验了。我不是个入门员工。但尽管过去的工作经验丰富,我仍然是个入门级的开发者,我还是个新手。别总…...
Python实战之小说下载神器(三)排行榜所有小说:最全热门小说合集,总有一款适合你,好多好多好多超赞的小说...(源码分享学习)
前言 这次的是一个系列内容 给大家讲解一下何一步一步实现一个完整的实战项目案例系列之 小说下载神器(三)(GUI界面化程序) 多线程采集小说下载、采集排行榜所有小说 哈喽!大家上午好啦,我是爱看小说的栗子…...
前端监控之用户行为监控实践1(数据收集)
前文对前端监控进行了简单介绍,起因是因为当前做的一个需求,老板要看当前项目的uv、pv信息。其实这是非常简单的统计。 但在最开始接到这个需求,却难倒我了。 现在进行简单的复盘,记录一下实现方法。 一、数据记录 用户行为从大…...
【网络原理7】认识HTTP
目录 一、HTTP协议的位置 二、HTTP协议的特点&应用场景 三、HTTP协议的格式的查看 Fiddler下载与使用 编辑 如何查看HTTP请求消息 编辑 如何查看HTTP响应数据包 如何默认开启HTTPS的解析功能 四、HTTP的请求数据包的格式含义 第一部分:请求行&…...
SPI实验
目录 一、SPI 简介 二、硬件原理 ECSPI3_SCLK ECSPI3_MISO和ECSPI3_MOSI ECSPI3_SS0 三、I.MX6U ECSPI 简介 ECSPIx_RXDATA ECSPIx_TXDATA ECSPIx_CONREG ECSPIx_CONFIGREG ECSPIx_PERIODREG编辑 ECSPIx_STATREG 四、ICM-20608 简介 五、代码编写 1、创建文件及文…...
去基线处理
目录detrend函数去除基线多项式拟合原函数BEADS 基线处理小波算法经验模态分解(EMD)参考detrend函数去除基线 detrend函数只能用于去除线性趋势,对于非线性的无能为力。 函数表达式:y scipy.signal.detrend(x): 从信号中删除线…...
模拟信号4-20mA /0-5V/0-75mV/0-100mV转RS-485/232,数据采集A/D转换模块 YL21
特点:● 模拟信号采集,隔离转换 RS-485/232输出● 采用12位AD转换器,测量精度优于0.1%● 通过RS-485/232接口可以程控校准模块精度● 信号输入 / 输出之间隔离耐压3000VDC ● 宽电源供电范围:8 ~ 32VDC● 可靠性高,编程…...
[USB]键盘数据格式以及按键键值
USB键盘数据包含8个字节 BYTE1 – 特殊按键 |–bit0: Left Control是否按下,按下为1 |–bit1: Left Shift 是否按下,按下为1 |–bit2: Left Alt 是否按下,按下为1 |–bit3: Left GUI(Windows键) 是否按下,…...
web客户端-websocket
1、websocket简介 WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,…...
mysql间隙锁
首先我们这里有一个表t,其中的数据如下图所示 注意哈 update由于操作的最新的值,所以是当前读! 另外一个事务插入 8的时候发生锁 而我对id为10的数据进行更新,却不会被锁住 分析:在执行当前读时,由于id7不存…...
华为OD机试 - 计算面积(Java) | 机试题+算法思路+考点+代码解析 【2023】
计算面积 绘图机器的绘图笔初始位i在原点(0.0)。 机器启动后其绘图笔按下面规则绘制直线: 1 )尝试沿着横向坐标轴正向绘制直线,直到给定的终点值E, 2 )期间可通过指令在纵坐标轴方向进行偏移。井同时绘制直线,偏移后按规则1绘制直线;指令的格式为X offsetY。表示在横坐标X…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
