zoukankan      html  css  js  c++  java
  • Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍

    场景

    什么是Netty

    Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。

    Netty 是基于 Java NIO 的异步事件驱动的网络应用框架,使用 Netty 可以快速开发网络应用,Netty 提供了高层次的抽象来简化 TCP 和 UDP 服务器的编程,但是你仍然可以使用底层的 API。

    Netty 的内部实现是很复杂的,但是 Netty 提供了简单易用的API从网络处理代码中解耦业务逻辑。Netty 是完全基于 NIO 实现的,所以整个 Netty 都是异步的。

    Netty 是最流行的 NIO 框架,它已经得到成百上千的商业、商用项目验证,许多框架和开源组件的底层 rpc 都是使用的 Netty,如 Dubbo、Elasticsearch 等等。

    这里使用IDEA和Gradle,也可以使用Maven作为依赖管理工具。

    在Windows中下载配置以及在IDEA中配置Gradle参照如下

    https://mp.csdn.net/console/editor/html/108578033

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    IDEA新建一个Gradle项目

    配置使用Java并设置JDK

    新建之后的项目目录

     

    此时会自动在build.gradle类似于Maven的pom.xml中引入了junit的依赖。

    这里需要引入Netty的依赖。

    浏览器打开Maven中央仓库地址

    https://mvnrepository.com/

    搜索netty-all

     

     

    选择稳定版本这里是4.1.52

    选择Gradle的依赖

    将其复制进IDEA下的build.gradle中

    dependencies {
        // https://mvnrepository.com/artifact/io.netty/netty-all
        compile group: 'io.netty', name: 'netty-all', version: '4.1.52.Final'
    }

    因为上面已经设置了自动导入依赖。

    所以保存后就能实现自动导入。

    同样在上面的gradle的配置的博客中设置了jar包的存储位置。

    来到配置的jar包的存储位置就可以看到jar包所在的位置。

    在项目中引入Netty后,在src下新建包,包下新建HelloWorldServer类作为服务端的启动类

    在启动类中新建main方法

    package com.badao.netty;
    
    import io.netty.bootstrap.ServerBootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.nio.NioServerSocketChannel;
    
    public class HelloWorldServer {
        public static void main(String[] args) throws  Exception
        {
            EventLoopGroup bossGroup = new NioEventLoopGroup();
            EventLoopGroup workerGroup = new NioEventLoopGroup();
            try{
                //服务端启动类-Netty提供的启动服务端的类
                ServerBootstrap serverBootstrap = new ServerBootstrap();
                //参数为两个事件组 前面的用来接收请求 后面的用来处理
                //childHandler 设置请求到了之后进行处理的处理器
                serverBootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class)
                .childHandler(new HelloWorldServerInitializer());
                //绑定端口
                ChannelFuture channelFuture = serverBootstrap.bind(70).sync();
                channelFuture.channel().closeFuture().sync();
            }finally {
                //关闭事件组
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }
        }
    }

    注意这里的都是引入的netty的包,不要引入nio的包。

    首先EventLoopGroup是事件循环组,可以认为是一个死循环,一直监听是否有连接然后处理。

    这里使用两个是Netty官方推荐,一个bossGroup只用来监听连接,然后交由后面的workerGroup进行处理。

    ServerBootstrap是Netty的启动服务端的类。

    分别设置两个group并设置通道为NioServerSocketChannel

    然后childHandler是设置对请求具体处理的处理器。这里新建了一个HelloWorldInititalizer类作为服务端初始化的类。

    下面绑定了70端口。

    所以在包下再新建类HelloWorldServerInitializer作为服务端初始化器,并使其继承ChannelInitializer

    然后重写initChannel方法,连接一旦被创建后就会执行此方法。

    package com.badao.netty;
    
    import io.netty.channel.Channel;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelPipeline;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.handler.codec.http.HttpServerCodec;
    
    //服务端初始化器
    public class HelloWorldServerInitializer extends ChannelInitializer<SocketChannel> {
    
    
        @Override
        protected void initChannel(SocketChannel ch) throws Exception {
            //连接一旦被创建后就会执行此方法
            ChannelPipeline channelPipeline = ch.pipeline();
            //在最后添加由Netty提供的处理器
            channelPipeline.addLast("httpServerCodec",new HttpServerCodec());
            channelPipeline.addLast("helloWorldServerHandler",new HelloWorldServerHandler());
        }
    }

    注意这里的继承的泛型里面的SocketChannel是在netty包下的。

    在方法中在处理的最后添加处理器,第一个添加的是Netty自带的处理器。

    后面再创建一个自定的处理器HelloWorldServerHandler

    前面的name可以自己定义。

    所以需要在包下再新建HelloWorldServerHandler处理器类并使其继承SimpleChannelInboundHandler

    然后重写其方法channelRead0

    此方法就是读取客户端发送过来的请求并返回响应。

    package com.badao.netty;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.buffer.Unpooled;
    import io.netty.channel.ChannelHandlerContext;
    import io.netty.channel.SimpleChannelInboundHandler;
    import io.netty.handler.codec.http.*;
    import io.netty.util.CharsetUtil;
    
    //自定义的处理器
    public class HelloWorldServerHandler extends SimpleChannelInboundHandler<HttpObject> {
        //此方法就是读取客户端发送过来的请求并返回响应
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
            if(msg instanceof HttpRequest)
            {
                //构造返回内容
                ByteBuf content = Unpooled.copiedBuffer("公众号:霸道的程序猿", CharsetUtil.UTF_8);
                //构造响应
                FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,content);
                //设置响应头类型
                response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");
                //设置响应头长度
                response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());
                //返回响应
                ctx.writeAndFlush(response);
            }
    
        }
    }

    在方法中构造返回的内容和响应头,然后将其返回响应。

    这样一个客户端,功能是接受到请求时返回字符串"公众号:霸道的程序猿",就搭建完成了。

    找到项目下的.idea下的gradle.xml,将下面的

    <option name="delegatedBuild" value="false" />

    改为false,如果没有则将这行加上

    这样就能使用java运行main方法,gradle就不会认为其是task了。

    运行最上面的服务端的main方法。

    如果没有输出任何报错则是运行成功。

    怎样去验证服务端搭建成功?

    这里可以使用curl去进行请求验证

    cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。
    它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。
    cURL还包含了用于程序开发的libcurl。

    cURL支持的通信协议有FTP、FTPS、HTTP、HTTPS、TFTP、SFTP、Gopher、SCP、Telnet、DICT、FILE、LDAP、LDAPS、IMAP、POP3、SMTP和RTSP。

    curl还支持SSL认证、HTTP POST、HTTP PUT、FTP上传, HTTP form based upload、proxies、HTTP/2、cookies、用户名+密码认证(Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos)、file transfer resume、proxy tunneling。

    这里因为是在Windows下,所以需要下载curl

    下载地址:

    https://curl.haxx.se/windows/

    这里下载64位的,将其解压到磁盘上的某目录。

    找到其目录下的bin目录,即curl.exe所在的目录。

    在此处打开cmd

    curl http://localhost:70

    博客园: https://www.cnblogs.com/badaoliumangqizhi/ 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。
  • 相关阅读:
    基于Grafana+SimpleJson的灵活报表解决方案
    Scala安装时的坑
    Windows批量添加防火墙例外端口
    VMware与Hyper-V
    InfluxDB:cannot use field in group by clause
    .Net版InfluxDB客户端使用时的一些坑
    KafkaManager中Group下不显示对应Topic的解决方案
    Linux下查看Go语言软件运行情况
    Flink升级到1.4版本遇到的坑
    spring cloud(一)带你进入分布式
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/13671045.html
Copyright © 2011-2022 走看看