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

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是一个抽象编码器&#xff0c;子类可重写encode方法把对象编码为ByteBuf输出。 MessageToByteEncoder继承自ChannelOutboundHandlerAdapter&#xff0c;encode在出站是被调用。 public class MyMessageEncoder extends MessageToB…...

ingress服务

user.default.svc.cluster.local是集群内部service的dns地址&#xff0c;集群外部想访问集群里面的service&#xff0c;可以通过LoadBalaner和NodePort。LoadBalaner可以获得一个公网ip&#xff1b;NodePort在宿主机上开一个端口&#xff0c;访问这个端口会把报文实际的转发到集…...

java 抽象类 详解

目录 一、抽象类概述&#xff1a; 二、抽象方法 : 1.概述 : 2.应用 : 3.特点 : 三、抽象类特点 : 1.关于abstract关键字 : 2.抽象类不能被实例化&#xff0c;只能创建其子类对象 : 3.抽象类子类的两个选择 &#xff1a; 四、抽象类的成员 : 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库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜任…...

BabylonJS之放烟花

一&#xff1a; 技术调研 1. 方案一&#xff1a;ParticleSystem 用ParticleSystem来实现每一束的烟花效果&#xff0c;如果浏览器支持WebGL2功能&#xff0c;使用GPUParticleSystem性能会有极大的提升。 优点&#xff1a; 烟花效果易实现且效果好。 缺点&#xff1a; 每一个P…...

vue3 布局样式的原理

style scoped <style scoped > 它的 CSS 只作用于当前组件中的元素&#xff0c;如果子组件只有一个根元素&#xff0c;也会被渗透 原理&#xff1a; 当我们再组建中使用scoped时&#xff0c;vue会自动为组件中所有元素生成一个随机的属性&#xff0c;形如&#xff1a;da…...

Qt程序使用路径方式和注意事项

Qt程序使用路径方式和注意事项 更多精彩内容&#x1f449;个人内容分类汇总 &#x1f448;&#x1f449;Qt开发经验 &#x1f448;文章目录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年学习编程并获得开发者工作

丢下自负 许多进入软件开发领域的人都是从最底层开始的&#xff0c;你可能会获得“初级开发者”的头衔。每天面临的问题是&#xff1a;我有十年的专业经验了。我不是个入门员工。但尽管过去的工作经验丰富&#xff0c;我仍然是个入门级的开发者&#xff0c;我还是个新手。别总…...

Python实战之小说下载神器(三)排行榜所有小说:最全热门小说合集,总有一款适合你,好多好多好多超赞的小说...(源码分享学习)

前言 这次的是一个系列内容 给大家讲解一下何一步一步实现一个完整的实战项目案例系列之 小说下载神器&#xff08;三&#xff09;&#xff08;GUI界面化程序&#xff09; 多线程采集小说下载、采集排行榜所有小说 哈喽&#xff01;大家上午好啦&#xff0c;我是爱看小说的栗子…...

前端监控之用户行为监控实践1(数据收集)

前文对前端监控进行了简单介绍&#xff0c;起因是因为当前做的一个需求&#xff0c;老板要看当前项目的uv、pv信息。其实这是非常简单的统计。 但在最开始接到这个需求&#xff0c;却难倒我了。 现在进行简单的复盘&#xff0c;记录一下实现方法。 一、数据记录 用户行为从大…...

【网络原理7】认识HTTP

目录 一、HTTP协议的位置 二、HTTP协议的特点&应用场景 三、HTTP协议的格式的查看 Fiddler下载与使用 ​编辑 如何查看HTTP请求消息 ​编辑 如何查看HTTP响应数据包 如何默认开启HTTPS的解析功能 四、HTTP的请求数据包的格式含义 第一部分&#xff1a;请求行&…...

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 基线处理小波算法经验模态分解&#xff08;EMD&#xff09;参考detrend函数去除基线 detrend函数只能用于去除线性趋势&#xff0c;对于非线性的无能为力。 函数表达式&#xff1a;y scipy.signal.detrend(x): 从信号中删除线…...

模拟信号4-20mA /0-5V/0-75mV/0-100mV转RS-485/232,数据采集A/D转换模块 YL21

特点&#xff1a;● 模拟信号采集&#xff0c;隔离转换 RS-485/232输出● 采用12位AD转换器&#xff0c;测量精度优于0.1%● 通过RS-485/232接口可以程控校准模块精度● 信号输入 / 输出之间隔离耐压3000VDC ● 宽电源供电范围&#xff1a;8 ~ 32VDC● 可靠性高&#xff0c;编程…...

[USB]键盘数据格式以及按键键值

USB键盘数据包含8个字节 BYTE1 – 特殊按键 |–bit0: Left Control是否按下&#xff0c;按下为1 |–bit1: Left Shift 是否按下&#xff0c;按下为1 |–bit2: Left Alt 是否按下&#xff0c;按下为1 |–bit3: Left GUI&#xff08;Windows键&#xff09; 是否按下&#xff0c;…...

web客户端-websocket

1、websocket简介 WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c…...

mysql间隙锁

首先我们这里有一个表t&#xff0c;其中的数据如下图所示 注意哈 update由于操作的最新的值&#xff0c;所以是当前读&#xff01; 另外一个事务插入 8的时候发生锁 而我对id为10的数据进行更新&#xff0c;却不会被锁住 分析&#xff1a;在执行当前读时&#xff0c;由于id7不存…...

华为OD机试 - 计算面积(Java) | 机试题+算法思路+考点+代码解析 【2023】

计算面积 绘图机器的绘图笔初始位i在原点(0.0)。 机器启动后其绘图笔按下面规则绘制直线: 1 )尝试沿着横向坐标轴正向绘制直线,直到给定的终点值E, 2 )期间可通过指令在纵坐标轴方向进行偏移。井同时绘制直线,偏移后按规则1绘制直线;指令的格式为X offsetY。表示在横坐标X…...

技术解析:ncmdump如何破解网易云音乐NCM格式加密机制

技术解析&#xff1a;ncmdump如何破解网易云音乐NCM格式加密机制 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 在数字音乐版权保护日益严格的今天&#xff0c;网易云音乐采用NCM格式对下载的音乐文件进行加密保护&#xff0c;这种…...

音频处理必看:短时傅里叶变换(STFT)在语音识别中的5个典型应用场景

音频处理必看&#xff1a;短时傅里叶变换(STFT)在语音识别中的5个典型应用场景 语音识别技术正以前所未有的速度渗透到智能家居、车载系统、客服机器人等日常场景中。作为这项技术的核心算法之一&#xff0c;短时傅里叶变换&#xff08;STFT&#xff09;就像一位隐形的音频解码…...

Python玩转微信自动化:除了监控聊天,uiautomation还能帮你自动保存文件、整理聊天记录

Python实现微信自动化管理&#xff1a;从文件归档到聊天记录整理 微信已经成为现代办公不可或缺的沟通工具&#xff0c;但随之而来的是海量文件管理和聊天记录整理的烦恼。每天手动保存图片、文档&#xff0c;再按日期分类&#xff0c;不仅耗时耗力&#xff0c;还容易遗漏重要…...

国风美学生成模型v1.0动态生成:制作一段水墨风格动画的逐帧渲染流程

国风美学生成模型v1.0动态生成&#xff1a;制作一段水墨风格动画的逐帧渲染流程 最近在玩一个挺有意思的国风美学模型&#xff0c;它生成的水墨画效果确实惊艳。但静态图片看久了&#xff0c;我就在想&#xff0c;能不能让这些画“动”起来&#xff1f;比如&#xff0c;让一滴…...

Phi-3-Mini-128K多模型协作实践:与Claude Code协同完成复杂编程任务

Phi-3-Mini-128K多模型协作实践&#xff1a;与Claude Code协同完成复杂编程任务 1. 引言 你有没有遇到过这样的情况&#xff1f;面对一个稍微复杂的编程任务&#xff0c;比如要搭建一个带用户管理的小型Web应用&#xff0c;你让一个AI助手来帮忙。它可能很快给你生成了一段登…...

Obsidian-skills日志系统:如何记录和分析AI技能使用情况

Obsidian-skills日志系统&#xff1a;如何记录和分析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性能实测&#xff1a;OpenClaw调用Qwen3-32B镜像的token消耗优化 1. 测试背景与设备环境 去年底入手RTX4090D显卡后&#xff0c;我一直想验证它在本地大模型推理场景的实际表现。最近在星图平台发现预置Qwen3-32B模型的优化镜像&#xff0c;正好配合OpenClaw做自动化…...

OpenClaw技能市场盘点:10个适配Phi-3-mini-128k-instruct的实用工具

OpenClaw技能市场盘点&#xff1a;10个适配Phi-3-mini-128k-instruct的实用工具 1. 为什么需要关注技能市场&#xff1f; 当我第一次在本地部署OpenClaw时&#xff0c;最让我惊喜的不是框架本身&#xff0c;而是它背后那个充满可能性的技能市场。作为一个长期与命令行打交道的…...

RWKV7-1.5B-g1a惊艳效果展示:三句话解释RWKV、产品文案、要点压缩真实输出

RWKV7-1.5B-g1a惊艳效果展示&#xff1a;三句话解释RWKV、产品文案、要点压缩真实输出 1. 模型简介与核心能力 rwkv7-1.5B-g1a 是基于新一代 RWKV-7 架构的多语言文本生成模型&#xff0c;专为轻量级应用场景优化。这个1.5B参数的模型在保持高效运行的同时&#xff0c;展现出…...

vscode-react-native完整功能解析:Android、iOS、Expo多平台支持终极指南

vscode-react-native完整功能解析&#xff1a;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…...