經過java進行網絡編程,netty能夠提升網絡通訊的開發效率的同時大大提升網絡通訊的效率。下面來看下如何使用netty進行高效編程。java
<dependency> <groupId>io.netty</gro <artifactId>netty-all</artifactId> <version>4.0.25.Final</version> </dependency>
netty3和netty4在編程api上有必定的區別,本篇是經過netty4進行實踐的。編程
io.netty.bootstrap.ServerBootstrap
netty服務端和客戶端的建立都是依賴於Bootstrap
句柄對象,下面咱們看下服務端是如何經過ServerBootstrap建立服務的。bootstrap
serverBootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup()).channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(nettyServerConfig.getListenPort())) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( new NettyEncoder(), new NettyDecoder(), new NettyConnetManageHandler(), new EchoServerHandler()); } }); ChannelFuture f = serverBootstrap.bind().sync();
你們去看源碼就能夠知道上面都是在初始化ServerBootstrap對象的屬性:api
io.netty.bootstrap.ServerBootstrap#group(io.netty.channel.EventLoopGroup, io.netty.channel.EventLoopGroup)
第一個參數是用於接收請求的EventLoopGroup,第二個參數是處理請求的EventLoopGroup。網絡
io.netty.bootstrap.AbstractBootstrap#channel
用於初始化channelFactory,channel建立爲NioServerSocketChannel的類型。ide
io.netty.bootstrap.AbstractBootstrap#localAddress(java.net.SocketAddress)
這個沒什麼好說的設置監聽的地址。oop
io.netty.bootstrap.ServerBootstrap#childHandler
數據流的handler處理器,上面咱們設置了四個handler,分別有數據流出和流進是待處理的handler鏈。學習
上面都是在初始化句柄接下來,serverBootstrap.bind().sync()
同步開啓服務。.net
io.netty.bootstrap.Bootstrap
bootstrap.group(new NioEventLoopGroup()).channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast( new NettyEncoder(), new NettyDecoder(), new NettyClientHandler()); } }); bootstrap.connect(new InetSocketAddress(ip, port));
客戶端句柄初始化相對來講簡單,初始化處理EventLoopGroup,channel factory,handler處理鏈,最後connect就能夠鏈接到netty的服務端了。netty
一、NettyEncoder
public class NettyEncoder extends MessageToByteEncoder<NettyCommand> { @Override public void encode(ChannelHandlerContext ctx, NettyCommand msg, ByteBuf out) throws Exception { out.writeBytes(msg.encode()); } }
二、NettyDecoder
public class NettyDecoder extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { byte[] tmpBuf = new byte[in.readableBytes()]; in.readBytes(tmpBuf); NettyCommand command = new NettyCommand(); out.add(command.decode(tmpBuf)); } }
傳輸對象的encode和decode都依賴於自定義的NettyCommand進行定義。
三、EchoServerHandler
class EchoServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { System.out.println("phase: channelReadComplete"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { System.out.println("phase: exceptionCaught"); cause.printStackTrace(); ctx.close(); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { NettyCommand requestCommand = (NettyCommand) msg; System.out.println("Server received: " + new String(requestCommand.getBody())); processMessageReceive(ctx, requestCommand); } }
四、NettyClientHandler
class NettyClientHandler extends SimpleChannelInboundHandler<NettyCommand> { @Override public void channelActive(ChannelHandlerContext ctx) { System.out.println("channelActive"); } @Override protected void channelRead0(ChannelHandlerContext ctx, NettyCommand msg) throws Exception { NettyCommand command = (NettyCommand) msg; processMessageReceive(ctx, command); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { //4 System.out.println("exceptionCaught"); cause.printStackTrace(); ctx.close(); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { System.out.println("channelReadComplete"); } }
到這裏一個簡單的hello netty就實現完畢了。
到這裏整個腦殼還不是太清晰,多是由於初次使用netty,不少深刻的原理性東西尚未充分的認識到,後面不斷學習昇華。