zoukankan      html  css  js  c++  java
  • netty编写http服务器

    public class TestServer {
    
        public static void main(String[] args) throws Exception{
            //创建两个线程组,一个bossGroup,一个workerGroup
            EventLoopGroup bossGroup = new NioEventLoopGroup();     //事件循环组,异步io
            EventLoopGroup workerGroup = new NioEventLoopGroup();
    
            try {
                ServerBootstrap serverBootstrap = new ServerBootstrap();                    //Bootstrap和ServerBootstrap是netty服务端启动的配置类
                serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)          //用到NioServerSocketChannel管道
                        .childHandler(new TestServerInitializer());                             //子处理器,(这里用到的是自己定义的初始化器)
    
                ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();            
                channelFuture.channel().closeFuture().sync();                   //关闭
            }
            finally{
                bossGroup.shutdownGracefully();             //优雅关闭
                workerGroup.shutdownGracefully();
            }
        }
    }

    首先定义两个基于NIO的事件循环组(EventLoopGroup),一个用于接收连接(bossGroup),另一个用于完成对应的连接处理(workerGroup)。

    ServerBootstrap是netty提供的帮助我们简化服务器启动的类,而我们需要再定义一个子处理器,其作用是在channel一旦被注册到处理器上之

    后就会运行代码。这时候绑定端口号并且同步,HTTPServer的轮廓就建好了。

    public class TestHttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
    
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {           //读取客户端发来的请求并向客户端返回响应的方法
    
            System.out.println(msg.getClass());
    
            System.out.println(ctx.channel().remoteAddress());
            Thread.sleep(8000);
    
            if(msg instanceof HttpRequest){
    
                HttpRequest httpRequest = (HttpRequest)msg;     //啰嗦一下,转换msg类型
    
                System.out.println("请求方法名:" + httpRequest.method().name());
    
                URI uri = new URI(httpRequest.uri());
    
                if("/favicon.ico".equals(uri.getPath()))
                {
                    System.out.println("请求favicon.con");
                    return;
                }
                ByteBuf content = Unpooled.copiedBuffer("Hello world !", CharsetUtil.UTF_8);                //ByteBuf对象是向客户端返回的内容
    
            //netty提供的简化的专门支撑响应的对象
                FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK,content);       //响应不是ServerResponses而是netty,HttpVersion1.1就是keep alive
    
                response.headers().set(HttpHeaderNames.CONTENT_TYPE,"text/plain");                              //设置response相关的头信息,内容类型
    
                response.headers().set(HttpHeaderNames.CONTENT_LENGTH,content.readableBytes());                 //响应内容长度
    
                ctx.writeAndFlush(response);
                ctx.channel().close();
    
            }
        }
    
        /**
         * @Description:   重写SimpleChannelInboundHandler中的方法,可以进一步了解连接创建的步骤
         *
         * @Author: KlayHu
         *
         * @Create: 2019/10/6 12:14
         **/
    
        
    
        @Override
        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
            super.handlerAdded(ctx);
            System.out.println("handler added");
        }
    
        @Override
        public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
            super.channelRegistered(ctx);
            System.out.println("channel registered");
        }
    
        @Override
        public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
            super.channelUnregistered(ctx);
            System.out.println("channel unregistered");
        }
    
        @Override
        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            super.channelActive(ctx);
            System.out.println("channel active");
        }
    
        @Override
        public void channelInactive(ChannelHandlerContext ctx) throws Exception {
            super.channelInactive(ctx);
            System.out.println("channel inactive");
        }

    ChannelHandlerContext是netty架构中很重要的对象,表示上下文获得相关的信息,比如远程地址,亦或是通过它获得的channel对象。而在我

    们自定义的子处理器中,重写SimpleChannelInboundHandler中的方法,可以便于我们了解连接创建的各个状态,在HTTP/1.1协议的响应模式

    下,通过终端命令curl或者浏览器访问本地端口均可。

  • 相关阅读:
    ExIco应用程序图标保存器1.0发布
    Object.defineProperty
    es6代理 proxy 学习
    node js学习记录
    css默认值列表
    关于 keyup keydown keypress
    转载一篇关于css选择器的,很透彻
    ......图片上传
    mimi
    css 开发心得
  • 原文地址:https://www.cnblogs.com/kkuuklay/p/11634682.html
Copyright © 2011-2022 走看看