如果你还不知道Netty是做什么的能做什么。那可以先简单的搜索了解一下。我Netty是一个NIO的框架,可以用于开发分布式的Java程序。具体能做什么,各位可以尽量发挥想象。技术,是服务于人而不是局限住人的。
如果你已经万事具备,那么我们先从一段代码开始。程序员们习惯的上手第一步,自然是"Hello world",不过Netty官网的例子却偏偏抛弃了"Hello world"。那我们就自己写一个最简单的"Hello world"的例子,作为上手。
1、首先创建 DiscardServerHandler 服务器端处理消息类:
package com.hpgary.netty4; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.CharsetUtil; /** * netty处理消息Handler * */ public class DiscardServerHandler extends SimpleChannelInboundHandler<ByteBuf> { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { System.out.println("异常"); } @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { /*打印接收的消息*/ System.out.println(msg.toString(CharsetUtil.UTF_8)); /*因为是网络传输,所以使用directBuffer, 使用 PooledByteBufAllocator ByteBuf池创建*/ ByteBuf byteBuf = ctx.alloc().directBuffer(); byteBuf.writeBytes("I got message\n".getBytes()); ctx.writeAndFlush(byteBuf); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { super.channelReadComplete(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { super.channelInactive(ctx); ctx.writeAndFlush("welcome\n"); } @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { } }
2、创建启动类:
package com.hpgary.netty4; import java.net.InetAddress; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; public class DiscardServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); ServerBootstrap b = new ServerBootstrap(); /** * 这一步是必须的,如果没有设置group将会报java.lang.IllegalStateException: group not * set异常 */ b.group(bossGroup, workerGroup); /** * ServerSocketChannel以NIO的selector为基础进行实现的,用来接收新的连接 * 这里告诉Channel如何获取新的连接. */ b.channel(NioServerSocketChannel.class); /*** * 这里的事件处理类经常会被用来处理一个最近的已经接收的Channel。 * ChannelInitializer是一个特殊的处理类, * 他的目的是帮助使用者配置一个新的Channel。 * 也许你想通过增加一些处理类比如NettyServerHandler来配置一个新的Channel * 或者其对应的ChannelPipeline来实现你的网络程序。 * 当你的程序变的复杂时,可能你会增加更多的处理类到pipline上, * 然后提取这些匿名类到最顶层的类上。 */ b.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); /*如果是传递和接收的是String字符串,就需要配置解压和压缩工具*/ // pipeline.addLast("decoder", new StringDecoder()); // pipeline.addLast("encoder", new StringEncoder()); /*配置接收数据的handler*/ pipeline.addLast("handler", new DiscardServerHandler()); } }); /*服务器端兵丁IP和端口,0.0.0.0表示任何IP都可以链接*/ ChannelFuture future = b.bind(InetAddress.getByName("0.0.0.0"), 8086).sync(); future.channel().closeFuture().sync(); } }
3、创建客户端处理数据handler
package com.hpgary.netty4; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.util.CharsetUtil; public class DiscardClientHandler extends SimpleChannelInboundHandler<ByteBuf> { @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { System.out.println(msg.toString(CharsetUtil.UTF_8)); } }
4、客户端启动程序
package com.hpgary.netty4; import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.commons.lang3.StringUtils; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; public class DiscardClient { public static void main(String[] args) throws Exception { EventLoopGroup workerGroup = new NioEventLoopGroup(); Bootstrap b = new Bootstrap(); b.group(workerGroup); b.channel(NioSocketChannel.class); b.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); pipeline.addLast("handler", new DiscardClientHandler()); } }); Channel ch = b.connect("127.0.0.1", 8086).sync().channel(); BufferedReader in = new BufferedReader(new InputStreamReader(System.in) ) ; while (true) { String line = in.readLine(); if (line == null) { continue; } ByteBuf buf = Unpooled.directBuffer(128); buf.writeBytes((line + StringUtils.LF).getBytes()); ch.writeAndFlush(buf); } } }