Netty学习-05-Netty

来源:互联网 发布:各个数据库的优缺点 编辑:程序博客网 时间:2024/05/20 13:06

Netty服务器的基本实现

Netty客户端如何处理响应消息

netty的编码与解码

   (DelimiterBasedFrameDecoderDelimitersByteToMessageCodec

<dependency>  <groupId>io.netty</groupId>   <artifactId>netty-all</artifactId>  <version>5.0.0.Alpha2</version></dependency>

服务端

import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;public class DiscardServer {private int port;public DiscardServer(int port) {this.port = port;}public void run() throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap(); // (2)b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new MyChannelInitializer()).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true); // (6)ChannelFuture f = b.bind(port).sync(); // (7)f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {int port = 8999;new DiscardServer(port).run();}}

import io.netty.channel.ChannelHandler.Sharable;import io.netty.channel.ChannelInitializer;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.DelimiterBasedFrameDecoder;import io.netty.handler.codec.Delimiters;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import org.xtwy.netty.codec.MyEncode;@Sharablepublic class MyChannelInitializer extends ChannelInitializer<SocketChannel> {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE, Delimiters.lineDelimiter()[0]));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(new MyEncode());ch.pipeline().addLast(new DiscardServerHandler());}}

import java.util.List;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;import io.netty.handler.codec.ByteToMessageCodec;import io.netty.handler.codec.Delimiters;public class MyEncode extends ByteToMessageCodec<String>{@Overrideprotected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out)throws Exception {out.writeBytes(msg.getBytes("UTF-8"));out.writeBytes(Delimiters.lineDelimiter()[0]);}@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in,List<Object> out) throws Exception {// TODO Auto-generated method stubInteger length = in.readInt();byte[] response = new byte[length];in.skipBytes(4).readBytes(response);out.add(response);}}


import io.netty.buffer.PooledByteBufAllocator;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;public class DiscardServerHandler extends ChannelHandlerAdapter {public static PooledByteBufAllocator allocator = new PooledByteBufAllocator();@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)throws Exception {ctx.close();}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {// ByteBuf buf = (ByteBuf)msg;// byte[] req = new byte[buf.readableBytes()];// buf.readBytes(req);// String body = new String(req,"UTF-8");// int s = 0;// while (buf.isReadable()) { // (1)// s = buf.readInt();// System.out.println(s);// }// ByteBuf wbuf =// allocator.buffer().writeBytes(("I have recieve"+msg+"\r\n").getBytes("utf-8"));//System.out.println(msg);// 处理业务代码String result = "I have recieve" + msg;ctx.writeAndFlush(result);}}


客户端===============================================================================

import org.xtwy.netty.codec.MyEncode;import org.xtwy.netty.constants.CommonConstant;import io.netty.bootstrap.Bootstrap;import io.netty.buffer.ByteBuf;import io.netty.buffer.PooledByteBufAllocator;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelOption;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;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.AttributeKey;public class DiscardClient {public static Bootstrap b;public static PooledByteBufAllocator allocator = new PooledByteBufAllocator();static {try {EventLoopGroup workerGroup = new NioEventLoopGroup();b = new Bootstrap(); // (1)b.group(workerGroup); // (2)b.channel(NioSocketChannel.class); // (3)b.option(ChannelOption.SO_KEEPALIVE, true); // (4)b.handler(new ChannelInitializer<SocketChannel>() {@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new DelimiterBasedFrameDecoder(Integer.MAX_VALUE,Delimiters.lineDelimiter()[0]));ch.pipeline().addLast(new StringDecoder());ch.pipeline().addLast(new MyEncode());ch.pipeline().addLast(new DiscardClientHandler());}});} catch (Exception e) {e.printStackTrace();}}public static Object startClient(int obj) throws Exception {ChannelFuture f = b.connect("localhost", 8999).sync();// f.channel().attr(AttributeKey.valueOf(CommonConstant.ATTRIBUTE_KEY)).set(obj);// ByteBuf buf = allocator.buffer().writeInt(obj);// ByteBuf buf =// allocator.buffer().writeBytes("hhllo".getBytes("UTF-8"));f.channel().writeAndFlush("hello");f.channel().closeFuture().sync();return f.channel().attr(AttributeKey.valueOf(CommonConstant.ATTRIBUTE_KEY)).get();}}

import org.xtwy.netty.constants.CommonConstant;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerAdapter;import io.netty.channel.ChannelHandlerContext;import io.netty.handler.codec.http.cors.CorsConfig.Builder;import io.netty.util.AttributeKey;public class DiscardClientHandler extends ChannelHandlerAdapter {@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {// int req = (int)// ctx.channel().attr(AttributeKey.valueOf(CommonConstant.ATTRIBUTE_KEY)).get();// System.out.println("请求数据为{}"+req);// ByteBuf buf =ctx.alloc().buffer().writeInt(req);// ctx.writeAndFlush(buf);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg)throws Exception {// ByteBuf buf = (ByteBuf)msg;// StringBuilder builder = new StringBuilder();// while (buf.isReadable()) { // (1)// builder.append((char) buf.readByte());// }//// ByteBuf buf = (ByteBuf)msg;// byte[] req = new byte[buf.readableBytes()];// buf.readBytes(req);// String body = new String(req,"UTF-8");ctx.channel().attr(AttributeKey.valueOf(CommonConstant.ATTRIBUTE_KEY)).set(msg.toString());// ctx.channel().close();ctx.close();}}


public class CommonConstant {public final static String ATTRIBUTE_KEY="Attribute_key";}


import org.junit.Test;import org.xtwy.netty.DiscardClient;public class NettyClientTest {@Testpublic void test01() throws Exception{for(int i=0;i<1;i++){long start = System.currentTimeMillis();Object obj = DiscardClient.startClient(1);if(obj==null){throw new RuntimeException("返回数据为空");}System.out.println(obj);long end = System.currentTimeMillis();System.out.println("第"+i+"循环耗时"+(end-start)+"ms");}}}







Netty客户端处理高并发,以及Netty5的线程模型讲解


当系统在运行过程中,如果频繁的进行线程上下文切换,会带来额外的性能损耗。多线程并发执行某个业务流程,业务开发者还需要时刻对线程安全保持警惕,哪些数据可能会被并发修改,如何保护?这不仅降低了开发效率,也会带来额外的性能损耗。Netty采用了串行化设计理念,从消息的读取、编码以及后续Handler的执行,始终都由IO线程NioEventLoop负责,这就意外着整个流程不会进行线程上下文的切换,数据也不会面临被并发修改的风险,对于用户而言,甚至不需要了解Netty的线程细节,这确实是个非常好的设计理念,它的工作原理图如下

http://www.infoq.com/cn/articles/netty-threading-model/


0 0
原创粉丝点击