初识Netty
本篇简单介绍一下Netty,使用Netty简单做一个实例程序。
概述
官方的介绍:
Netty is an asynchronous event-driven network application framework
for rapid development of maintainable high performance protocol servers & clients.
Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。
创建Maven项目
添加依赖
1 2 3 4 5 <dependency > <groupId > io.netty</groupId > <artifactId > netty-all</artifactId > <version > 4.1.63.Final</version > </dependency >
创建服务端
创建服务端启动类
graph LR
A(创建线程组)-->B(创建ServerBootstrap)
B-->C(为Bootstrap设置线程组)
C-->D(设置通道实现类型)
D-->E(设置option参数)
E(设置option参数)-->F(设置自定义Handler流水线)
F-->G(绑定端口)
G-->H(启动服务端)
H-->I(等待通讯结束关闭线程组)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public class MyServer { public static void main (String[] args) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG,128 ) .childOption(ChannelOption.SO_KEEPALIVE,true ) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel (SocketChannel socketChannel) { socketChannel.pipeline().addLast(new MyServerHandler()); } }); System.out.println("----Netty服务端准备就绪---" ); ChannelFuture channelFuture = bootstrap.bind(5555 ).sync(); channelFuture.channel().closeFuture().sync(); }finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
创建服务端信息处理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 public class MyServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead (ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf = (ByteBuf) msg; System.out.println("服务端收到客户端" + ctx.channel().remoteAddress() + "发送的消息:" + byteBuf.toString(CharsetUtil.UTF_8)); } @Override public void channelReadComplete (ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(Unpooled.copiedBuffer("服务端已收到消息" , CharsetUtil.UTF_8)); } @Override public void userEventTriggered (ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent){ IdleStateEvent event=(IdleStateEvent) evt; System.out.println(event.state()); } super .userEventTriggered(ctx, evt); } @Override public void exceptionCaught (ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); } }
创建客户端
创建客户端启动类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class MyClient { public static void main (String[] args) throws InterruptedException { NioEventLoopGroup eventExecutors = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventExecutors) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel (SocketChannel socketChannel) { socketChannel.pipeline().addLast(new MyClientHandler()); } }); System.out.println("=====客户端准备就绪=====" ); ChannelFuture channelFuture = bootstrap.connect("127.0.0.1" ,5555 ).sync(); channelFuture.channel().closeFuture().sync(); }finally { eventExecutors.shutdownGracefully(); } } }
创建客户端消息处理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class MyClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive (ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(Unpooled.copiedBuffer("这里是来自客户端的消息" , CharsetUtil.UTF_8)); } @Override public void channelRead (ChannelHandlerContext ctx, Object msg) { ByteBuf byteBuf = (ByteBuf) msg; System.out.println("客户端收到服务端" + ctx.channel().remoteAddress() + "的消息:" + byteBuf.toString(CharsetUtil.UTF_8)); } }
Bootstrap启动流程图
graph LR
A(创建线程组)-->B(创建ServerBootstrap)
B-->C(为Bootstrap设置线程组)
C-->D(设置通道实现类型)
D-->E(设置option参数)
E(设置option参数)-->F(设置自定义Handler流水线)
F-->G(绑定端口)
G-->H(启动服务端)
H-->I(等待通讯结束关闭线程组)
Netty的特性与重要组件
TaskQueue任务队列
如果Handler处理器有长时间的业务处理,可以使用TaskQueue异步处理。
测试 & 结果
MyServer启动后,启动MyServer的控制台会输出----Netty服务端准备就绪---
MyClient启动后
MyClient控制台打印=====客户端准备就绪=====
MyServer控制台打印服务端收到客户端/127.0.0.1:53000发送的消息:这里是来自客户端的消息
(由于客户端通道就绪后自动发送消息,故服务端收到了客户端的消息)
MyClient控制台打印客户端收到服务端/127.0.0.1:5555的消息:服务端已收到消息
(此消息为服务端收到消息之后的响应)
附录