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…...
技术解析:ncmdump如何破解网易云音乐NCM格式加密机制
技术解析:ncmdump如何破解网易云音乐NCM格式加密机制 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 在数字音乐版权保护日益严格的今天,网易云音乐采用NCM格式对下载的音乐文件进行加密保护,这种…...
音频处理必看:短时傅里叶变换(STFT)在语音识别中的5个典型应用场景
音频处理必看:短时傅里叶变换(STFT)在语音识别中的5个典型应用场景 语音识别技术正以前所未有的速度渗透到智能家居、车载系统、客服机器人等日常场景中。作为这项技术的核心算法之一,短时傅里叶变换(STFT)就像一位隐形的音频解码…...
Python玩转微信自动化:除了监控聊天,uiautomation还能帮你自动保存文件、整理聊天记录
Python实现微信自动化管理:从文件归档到聊天记录整理 微信已经成为现代办公不可或缺的沟通工具,但随之而来的是海量文件管理和聊天记录整理的烦恼。每天手动保存图片、文档,再按日期分类,不仅耗时耗力,还容易遗漏重要…...
国风美学生成模型v1.0动态生成:制作一段水墨风格动画的逐帧渲染流程
国风美学生成模型v1.0动态生成:制作一段水墨风格动画的逐帧渲染流程 最近在玩一个挺有意思的国风美学模型,它生成的水墨画效果确实惊艳。但静态图片看久了,我就在想,能不能让这些画“动”起来?比如,让一滴…...
Phi-3-Mini-128K多模型协作实践:与Claude Code协同完成复杂编程任务
Phi-3-Mini-128K多模型协作实践:与Claude Code协同完成复杂编程任务 1. 引言 你有没有遇到过这样的情况?面对一个稍微复杂的编程任务,比如要搭建一个带用户管理的小型Web应用,你让一个AI助手来帮忙。它可能很快给你生成了一段登…...
Obsidian-skills日志系统:如何记录和分析AI技能使用情况
Obsidian-skills日志系统:如何记录和分析AI技能使用情况 【免费下载链接】obsidian-skills Agent skills for Obsidian. Teach your agent to use Markdown, Bases, JSON Canvas, and use the CLI. 项目地址: https://gitcode.com/GitHub_Trending/ob/obsidian-sk…...
RTX4090D性能实测:OpenClaw调用Qwen3-32B镜像的token消耗优化
RTX4090D性能实测:OpenClaw调用Qwen3-32B镜像的token消耗优化 1. 测试背景与设备环境 去年底入手RTX4090D显卡后,我一直想验证它在本地大模型推理场景的实际表现。最近在星图平台发现预置Qwen3-32B模型的优化镜像,正好配合OpenClaw做自动化…...
OpenClaw技能市场盘点:10个适配Phi-3-mini-128k-instruct的实用工具
OpenClaw技能市场盘点:10个适配Phi-3-mini-128k-instruct的实用工具 1. 为什么需要关注技能市场? 当我第一次在本地部署OpenClaw时,最让我惊喜的不是框架本身,而是它背后那个充满可能性的技能市场。作为一个长期与命令行打交道的…...
RWKV7-1.5B-g1a惊艳效果展示:三句话解释RWKV、产品文案、要点压缩真实输出
RWKV7-1.5B-g1a惊艳效果展示:三句话解释RWKV、产品文案、要点压缩真实输出 1. 模型简介与核心能力 rwkv7-1.5B-g1a 是基于新一代 RWKV-7 架构的多语言文本生成模型,专为轻量级应用场景优化。这个1.5B参数的模型在保持高效运行的同时,展现出…...
vscode-react-native完整功能解析:Android、iOS、Expo多平台支持终极指南
vscode-react-native完整功能解析:Android、iOS、Expo多平台支持终极指南 【免费下载链接】vscode-react-native VSCode extension for React Native - supports debugging and editor integration 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-react-nat…...
