zoukankan      html  css  js  c++  java
  • 初识Netty

    Netty是什么

      参考文献:极客时间傅健老师的《Netty源码剖析与实战》Talk is cheap.show me the code!

      官网(https://netty.io/)表明:“Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.”,翻译过来就是:Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。简单的拆分可以理解:

    ①本质:网络应用程序框架

    ②实现:异步、事件驱动

    ③特性:高性能、可维护、快速开发

    ④用途:开发服务器和客户端

       这是官网给的一张结构图:

    不难看出Nettty一共有三个部分,最底层是核心层,从下往上看,最下面是"零拷贝Buffer",往上一格是"通信层API",再上一格则是"拓展的事件模型",左上是传输层服务,包括Http的Tunnel,TCP的Socket,UDP的Datagram等等,右上则是Netty支持的各种各样的协议,比如我们常说的HTTP协议,WebSocket协议,Google的ProtoBuf协议等等。

    第一个HelloWorld

      用InterlliJ IDEA建立一个Maven工程,在pom.xml配置文件加入Netty的依赖

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

    编写服务器端MyService.java

    package com.lql.netty;
    
    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.logging.LogLevel;
    import io.netty.handler.logging.LoggingHandler;
    
    /**
     * @author: lql
     * @date: 2019.10.14
     * Description:     第一个Netty程序     服务器
     */
    public class MyServer {
    
    
        public static void main(String[] args) throws Exception {
    
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
    
            try {
                ServerBootstrap sb = new ServerBootstrap();
                sb.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                        .handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast(new LoggingHandler(LogLevel.INFO));
                        p.addLast(new MyServerHandler());
                    }
                });
    
                ChannelFuture f = sb.bind(8090).sync();
                f.channel().closeFuture().sync();
            } finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
    
        }
    }

    编写MyServerHandler.java

    package com.lql.netty;
    
    import io.netty.channel.ChannelHandler.Sharable;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    /**
     * @author: lql
     * @date: 2019.10.14
     * Description:
     */
    @Sharable
    public class MyServerHandler extends ChannelInboundHandlerAdapter {
    
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    
            ctx.write(msg);
        }
    
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
            ctx.flush();
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    
            cause.printStackTrace();
            ctx.close();
        }
    }

    再来编写客户端MyClient.java

    package com.lql.netty;
    
    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.*;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioSocketChannel;
    import io.netty.handler.logging.LogLevel;
    import io.netty.handler.logging.LoggingHandler;
    
    /**
     * @author: lql
     * @date: 2019.10.14
     * Description: 第一个Netty程序     客户端
     */
    public class MyClient {
    
        public static void main(String[] args) throws Exception {
            //客户端只需要一个事件循环组
            EventLoopGroup group = new NioEventLoopGroup();
    
            try {
                Bootstrap b = new Bootstrap();
                b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel socketChannel) throws Exception {
                                ChannelPipeline p = socketChannel.pipeline();
                                p.addLast(new LoggingHandler(LogLevel.INFO));
                                p.addLast(new MyClientHandle());
                            }
                        });
    
                //开始客户端
                ChannelFuture f = b.connect("127.0.0.1",8090).sync();
                //等待连接关闭
                f.channel().closeFuture().sync();
    
            } finally {
                //优雅关闭
                group.shutdownGracefully();
            }
    
        }
    }

    同样,创建MyClientHandle.java

    package com.lql.netty;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.ChannelInboundHandlerAdapter;
    
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author: lql
     * @date: 2019.10.14
     * Description:
     */
    public class MyClientHandle extends ChannelInboundHandlerAdapter{
    
        private final ByteBuf firstMessage;
    
        public MyClientHandle() {
            firstMessage = Unpooled.wrappedBuffer("I am echo message".getBytes());
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) {
            ctx.writeAndFlush(firstMessage);
        }
    
        @Override
        public void channelRead(ChannelHandlerContext ctx, Object msg) {
            ctx.write(msg);
        }
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) throws InterruptedException {
            TimeUnit.SECONDS.sleep(3);
            ctx.flush();
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }

    先启动服务器,后启动客户端,结果是可行的!

    Netty也可以和Spring mvc一样。如下所示:

    建立HttpServer.java

    package com.lql.netty;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.*;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    import io.netty.handler.codec.http.HttpServerCodec;
    import io.netty.handler.codec.http.HttpServerExpectContinueHandler;
    import io.netty.handler.logging.LogLevel;
    import io.netty.handler.logging.LoggingHandler;
    
    /**
     * @author: lql
     * @date: 2019.10.14
     * Description:
     * Created with IntelliJ IDEA
     */
    public class HttpServer {
    
    
        public static void main(String[] args) throws Exception {
    
            EventLoopGroup bossGroup = new NioEventLoopGroup(1);
            EventLoopGroup workerGroup = new NioEventLoopGroup();
    
            try {
                ServerBootstrap b = new ServerBootstrap();
                b.group(bossGroup, workerGroup)
                        .channel(NioServerSocketChannel.class)
                        .handler(new LoggingHandler(LogLevel.INFO))
                        .childHandler(new ChannelInitializer() {
                            protected void initChannel(Channel ch) throws Exception {
                                ChannelPipeline p = ch.pipeline();
                                p.addLast(new HttpServerCodec());
                                p.addLast(new HttpServerExpectContinueHandler());
                                p.addLast(new HttpServerHandler());
                            }
                        });
    
                ChannelFuture channelFuture = b.bind(8899).sync();
                channelFuture.channel().closeFuture().sync();
    
            }finally {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }

    再建立HttpServerHandler.java

    package com.lql.netty;
    
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.handler.codec.http.*;
    
    /**
     * @author: lql
     * @date: 2019.10.14
     * Description:
     * Created with IntelliJ IDEA
     */
    public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
    
    
        private static final byte[] CONTENT = "helloworld".getBytes();
    
        @Override
        public void channelReadComplete(ChannelHandlerContext ctx) {
            ctx.flush();
        }
    
        @Override
        public void channelRead0(ChannelHandlerContext ctx, HttpObject msg) {
            if (msg instanceof HttpRequest) {
                HttpRequest req = (HttpRequest) msg;
    
                FullHttpResponse response = new DefaultFullHttpResponse(req.protocolVersion(), HttpResponseStatus.OK,
                        Unpooled.wrappedBuffer(CONTENT));
                response.headers()
                        .set(HttpHeaderNames.CONTENT_TYPE, "text/plain")
                        .setInt(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
                ctx.write(response);
            }
        }
    
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
            cause.printStackTrace();
            ctx.close();
        }
    }

    启动HttpServer:在网址输“http://localhost:8899/”,显示如下:

    至此,Netty的HelloWorld已经写完了!

  • 相关阅读:
    1. MySQL的安装与配置
    18. SQL优化
    19. 优化数据库对象
    20. 锁问题
    21. 优化MySQL Server
    整合SSM基本配置
    第七周实验报告(五)&周总结
    Java作业-实验四
    Java实验三
    在IDEA中创建maven工程添加webapp
  • 原文地址:https://www.cnblogs.com/-qilin/p/11671763.html
Copyright © 2011-2022 走看看