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

2.Netty简单应用

引入Maven依赖

<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId><version>4.1.49.Final</version> 
</dependency>

服务端的管道处理器

public class NettyServerHandler extends ChannelInboundHandlerAdapter {//读取数据实际(这里我们可以读取客户端发送的消息)/*1. ChannelHandlerContext ctx:上下文对象, 含有 管道pipeline , 通道channel, 地址2. Object msg: 就是客户端发送的数据 默认Object*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("server ctx =" + ctx);Channel channel = ctx.channel();//将 msg 转成一个 ByteBuf//ByteBuf 是 Netty 提供的,不是 NIO 的 ByteBuffer.ByteBuf buf = (ByteBuf) msg;System.out.println("客户端发送消息是:" + buf.toString(CharsetUtil.UTF_8));System.out.println("客户端地址:" + channel.remoteAddress());}//数据读取完毕@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {//writeAndFlush 是 write + flush//将数据写入到缓存,并刷新//一般讲,我们对这个发送的数据进行编码ctx.writeAndFlush(Unpooled.copiedBuffer("公司最近账户没啥钱,再等几天吧!", CharsetUtil.UTF_8));}//处理异常, 一般是需要关闭通道@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.close();}
}

NettyServerHandler继承自ChannelInboundHandlerAdapter,这个类实现了ChannelInboundHandler接口。ChannelInboundHandler提供了许多事件处理的接口方法。

这里覆盖了channelRead()事件处理方法。每当从客户端收到新的数据时,这个方法会在收到消息时被调用。

channelReadComplete()事件处理方法是数据读取完毕时被调用,通过调用ChannelHandlerContextwriteAndFlush()方法,把消息写入管道,并最终发送给客户端。

exceptionCaught()事件处理方法是,当出现Throwable对象时才会被调用。

服务端主程序

public class NettyServer {public static void main(String[] args) throws Exception {//创建BossGroup 和 WorkerGroup//说明//1. 创建两个线程组 bossGroup 和 workerGroup//2. bossGroup 只是处理连接请求 , 真正的和客户端业务处理,会交给 workerGroup完成//3. 两个都是无限循环//4. bossGroup 和 workerGroup 含有的子线程(NioEventLoop)的个数//   默认实际 cpu核数 * 2//EventLoopGroup bossGroup = new NioEventLoopGroup(1);EventLoopGroup workerGroup = new NioEventLoopGroup(); //8try {//创建服务器端的启动对象,配置参数ServerBootstrap bootstrap = new ServerBootstrap();//使用链式编程来进行设置bootstrap.group(bossGroup, workerGroup) //设置两个线程组.channel(NioServerSocketChannel.class) //bossGroup使用NioSocketChannel 作为服务器的通道实现.option(ChannelOption.SO_BACKLOG, 128) // 设置线程队列得到连接个数 option主要是针对boss线程组,.childOption(ChannelOption.SO_KEEPALIVE, true) //设置保持活动连接状态 child主要是针对worker线程组.childHandler(new ChannelInitializer<SocketChannel>() {//workerGroup使用 SocketChannel创建一个通道初始化对象																														(匿名对象)//给pipeline 设置处理器@Overrideprotected void initChannel(SocketChannel ch) throws Exception {//可以使用一个集合管理 SocketChannel, 再推送消息时,可以将业务加入到各个channel 对应的 NIOEventLoop 的 									taskQueue 或者 scheduleTaskQueuech.pipeline().addLast(new NettyServerHandler());}}); // 给我们的workerGroup 的 EventLoop 对应的管道设置处理器System.out.println(".....服务器 is ready...");//绑定一个端口并且同步, 生成了一个 ChannelFuture 对象//启动服务器(并绑定端口)ChannelFuture cf = bootstrap.bind(7788).sync();//给cf 注册监听器,监控我们关心的事件cf.addListener(new ChannelFutureListener() {@Overridepublic void operationComplete(ChannelFuture future) throws Exception {if (cf.isSuccess()) {System.out.println("服务已启动,端口号为7788...");} else {System.out.println("服务启动失败...");}}});//对关闭通道进行监听cf.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}
}

NioEventLoopGroup是用来处理I/O操作的多线程事件循环器。Netty 提供了许多不同的EventLoopGroup的实现来处理不同的传输。

上面的服务端应用中,有两个NioEventLoopGroup被使用。第一个叫作bossGroup,用来接收进来的连接。第二个叫作workerGroup,用来处理已经被接收的连接,一旦 bossGroup接收连接,就会把连接的信息注册到workerGroup上。

ServerBootstrap是一个NIO服务的引导启动类。可以在这个服务中直接使用Channel

  • group方法用于 设置EventLoopGroup
  • 通过Channel方法,可以指定新连接进来的Channel类型为NioServerSocketChannel类。
  • childHandler用于指定ChannelHandler,也就是前面实现的NettyServerHandler
  • 可以通过option设置指定的Channel来实现NioServerSocketChannel的配置参数。
  • childOption主要设置SocketChannel的子Channel的选项。
  • bind用于绑定端口启动服务。

客户端管道处理器

public class NettyClientHandler extends ChannelInboundHandlerAdapter {//当通道就绪就会触发该方法@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("client ctx =" + ctx);ctx.writeAndFlush(Unpooled.copiedBuffer("老板,工资什么时候发给我啊?", CharsetUtil.UTF_8));}//当通道有读取事件时,会触发@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {ByteBuf buf = (ByteBuf) msg;System.out.println("服务器回复的消息:" + buf.toString(CharsetUtil.UTF_8));System.out.println("服务器的地址: "+ ctx.channel().remoteAddress());}//处理异常, 一般是需要关闭通道@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();}
}

channelRead方法中将接收到的消息转化为字符串,方便在控制台上打印出来。

channelRead接收到的消息类型为ByteBufByteBuf提供了转为字符串的方便方法。

客户端主程序

public class NettyClient {public static void main(String[] args) throws Exception {//客户端需要一个事件循环组EventLoopGroup group = new NioEventLoopGroup();try {//创建客户端启动对象//注意客户端使用的不是 ServerBootstrap 而是 BootstrapBootstrap bootstrap = new Bootstrap();//设置相关参数bootstrap.group(group) //设置线程组.channel(NioSocketChannel.class) // 设置客户端通道的实现类(反射).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new NettyClientHandler()); //加入自己的处理器}});System.out.println("客户端 ok..");//启动客户端去连接服务器端//关于 ChannelFuture 要分析,涉及到netty的异步模型ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 7788).sync();//给关闭通道进行监听channelFuture.channel().closeFuture().sync();} finally {group.shutdownGracefully();}}
}

客户端只需要一个NioEventLoopGroup就可以了。

测试运行结果

分别启动服务器 NettyServer 和客户端 NettyClient程序

服务端控制台输出内容:

.....服务器 is ready...
服务已启动,端口号为7788...
server ctx =ChannelHandlerContext(NettyServerHandler#0,
[id: 0xa1b2233c, L:/127.0.0.1:7788 - R:/127.0.0.1:63239])
客户端发送消息是:老板,工资什么时候发给我啊?
客户端地址:/127.0.0.1:63239

客户端控制台输出内容:

客户端 ok.. client ctx =ChannelHandlerContext(NettyClientHandler#0, 
[id: 0x21d6f98e, L:/127.0.0.1:63239 - R:/127.0.0.1:7788]) 
服务器回复的消息:公司最近账户没啥钱,再等几天吧! 服务器的地址: /127.0.0.1:7788

至此,一个简单的基于Netty开发的服务端和客户端就完成了。

相关文章:

2.Netty简单应用

引入Maven依赖 <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId><version>4.1.49.Final</version> </dependency>服务端的管道处理器 public class NettyServerHandler extends ChannelInbou…...

80个10倍提升Excel技能的ChatGPT提示

你是否厌倦了在使用Excel时感觉像个新手&#xff1f;你是否想将你的技能提升到更高的水平&#xff0c;成为真正的Excel大师&#xff1f;嗯&#xff0c;如果你正在使用ChatGPT&#xff0c;那么成为Excel专家简直易如反掌。 你只需要了解一些最有用的Excel提示&#xff0c;就能在…...

jenkins结合k8s部署动态slave

1、完成k8s连接 在完成jenkins的部署后现安装kubernets的插件 如果jenkins 是部署在k8s集群中只需要填写一下 如果是非本集群的部署则需要填写证书等 cat ./config echo ‘certificate-authority-data-value’ | base64 -d > ./ca.crt echo ‘client-certificate-data’ |…...

搜索引擎Elasticsearch基础与实践

倒排索引 将文档中的内容分词&#xff0c;然后形成词条。记录每条词条与数据的唯一表示如id的对应关系&#xff0c;形成的产物就是倒排索引&#xff0c;如下图&#xff1a; ElasticSearch数据的存储和搜索原理 这里的索引库相当于mysql中的database。一个文档&#xff08;do…...

vue项目electron打包

1.设置国内镜像 npm config edit 命令行输入后会弹出npm的配置文档&#xff0c;需要文档末尾加入 electron_mirrorhttps://npm.taobao.org/mirrors/electron/ electron-builder-binaries_mirrorhttps://npm.taobao.org/mirrors/electron-builder-binaries/ 2.全局安装electron …...

英伟达发布RAPIDS cuDF框架 pandas在GPU上运行速度快了150倍

11月9日 消息&#xff1a;Nvidia 发布了一款名为 RAPIDS cuDF 的新版本&#xff0c;据称可以将 pandas 运行在 GPU 上&#xff0c;并且性能提升了150倍。pandas 是一款流行的基于 Python 的数据框架库&#xff0c;用于数据处理和分析。它的开源版本由 Wes McKinney 开发和发布&…...

(a)Mask RCNN总体流程

&#xff08;a&#xff09;Mask RCNN总体流程 一.Mask RCNN 架构 自己整理了一份Mask RCNN架构图如下&#xff0c;其中绿色模块只有推理过程才会涉及。 核心模块包括&#xff1a;数据预处理&#xff0c;骨干网络&#xff0c;区域提议网络&#xff0c;FastRCNN分支&#xff0c…...

浅谈数据中心机房末端配电技术与产品监控选型-安科瑞黄安南

摘要 数据中心机房末端配电的可靠性、稳定性和可维护性直接关系到IT设备的安全供电。数据中心的末端配电技术主要有两种&#xff0c;一种采用列头柜加电缆配电&#xff0c;另一种是智能小母线配电。分别对两种配电技术进行了介绍和探讨&#xff0c;最后对两种配电方式进行了对…...

红包算法 java实现

红包算法 首先&#xff0c;如果红包只有一个&#xff0c;本轮直接使用全部金额&#xff0c;确保红包发完。 然后&#xff0c; 计算出本次红包最少要领取多少&#xff0c;才能保证红包领完&#xff0c;即本轮下水位&#xff1b; 本轮最多领取多少&#xff0c;才能保证每个人都…...

MVCC中的可见性算法

在之前的文章 MVCC详解-CSDN博客中我们已经介绍过了MVCC的原理&#xff08;read viewundo log&#xff09;&#xff0c;今天来详细的说一下readview的匹配规则&#xff08;可见性算法&#xff09; 隔离级别在RC&#xff0c;RR的前提下 Read View是如何保证可见性判断的呢&#…...

Leetcode73矩阵置零

1110-3 代码&#xff1a; 和题解思路差不多 class Solution {public void setZeroes(int[][] matrix) {Set<Integer> setr new HashSet<>();Set<Integer> setc new HashSet<>();for(int i0;i<matrix.length;i){for(int j0;j<matrix[0].leng…...

linux重要的目录之proc和dev目录

/proc/目录 虚拟文件系统&#xff0c;将内核与进程状态归档为文本文件&#xff08;系统信息都存放这目录下&#xff09; Linux系统上的/proc目录是一种文件系统&#xff0c;即proc文件系统。与其它常见的文件系统不同的是&#xff0c;/proc是一种伪文件系统&#xff08;也即虚拟…...

【组件自定义事件+全局事件总线+消息订阅与发布+TodoList案例——编辑+过度与动画】

组件自定义事件全局事件总线消息订阅与发布TodoList案例——编辑过度与动画 1 组件自定义事件1.1 绑定1.2 解绑1.3 总结1.4 TodoList案例——自定义事件 2 全局事件总线2.1 理解2.2 步骤2.3 TodoList案例——事件总线 3 消息订阅与发布3.1 理解3.2 TodoList案例——消息的订阅与…...

单独封装export default .js 在引入

...

【带头学C++】----- 三、指针章 ---- 3.11 补充重要指针知识(二,拓展基础知识)

1.指针与函数 1.1指针变量作为函数的参数 如果想在函数内部修改外部变量的值&#xff0c;可以将外部变量的地址传递给函数。 在C/C中&#xff0c;函数的参数传递方式有值传递&#xff08;传递变量的副本&#xff09;和引用传递&#xff08;传递变量的地址&#xff09;。如果希…...

Jmeter分布式性能测试细节+常见问题解决,资深老鸟带你避坑...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Jmeter分布式测试…...

动态表单获取某一项值

<template><div><el-form :model"form" :rules"rules" ref"form"><el-row v-for"(item,index) in form.list" :key"index"><el-col :span"6"><el-form-item label"用户名称…...

短路表达式

什么是短路表达式 作为"&&"和"||"操作符的操作数表达式&#xff0c;这些表达式在进行求值时&#xff0c;只要最终的结果已经可以确定是真或假&#xff0c;求值过程便告终止&#xff0c;这称之为短路求值。这是这两个操作符的一个重要属性。 而在j…...

风力发电场集中监控系统解决方案

安科瑞 崔丽洁 作为清洁能源之一&#xff0c;风力发电场近几年装机容量快速增长。8月17日&#xff0c;国家能源局发布1-7月份全国电力工业统计数据。截至7月底&#xff0c;全国累计发电装机容量约27.4亿千瓦&#xff0c;同比增长11.5%。其中&#xff0c;太阳能发电装机容量约4.…...

SpringDataJpa(二)

三、Spring Data JPA概述 Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架&#xff0c;可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能&#xff0c;且易于扩展&#xff01;学习并使用 Spring D…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...