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…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
