基于Netty的通信服务端编写

我这次是按照NIO模型编写的一个服务端

public class HelloServer {
    public static void main(String[] args) throws Exception {
        //定义一对线程组
        //主线程组,用于接收客户端的连接,但是不做任何处理,跟老板一样,不做事
        EventLoopGroup bossGroup=new NioEventLoopGroup();
        //从线程组,老板线程组会把任务丢给她,让手下线程组去做任务
        EventLoopGroup workerGroup=new NioEventLoopGroup();
    try {
    //netty服务器的创建,ServerBootstrap 是一个启动类
    ServerBootstrap serverBootstrap = new ServerBootstrap();
    serverBootstrap.group(bossGroup, workerGroup)    //设置主从线程组
            .channel(NioServerSocketChannel.class)          //设置nio的双向通道
            .childHandler(new HelloServerInitializer());                            //子处理器,用于处理workerGroup

    //启动server,并且设置8088为启动的端口号,同时启动方式为同步
    ChannelFuture channelFuture = serverBootstrap.bind(8088).sync();

    //监听关闭的channel,设置位同步方式
    channelFuture.channel().closeFuture().sync();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
    }
}
复制代码

NIO模型中,服务端有两个线程组,一个线程组是用来完成客户端到服务端连接的,另一个线程组是用来处理IO操作的,通过ServerBootstrap这个类的实例绑定在一起。

//初始化器,channel注册后,会执行里面的相应的初始化方式
public class HelloServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        //通过Socketchannel去获取对应的管道
        ChannelPipeline pipeline=channel.pipeline();

        //通过管道
        //HttpSeverCodec是由netty自己提供的助手类,可以理解为拦截器
        //当请求到服务端,我们需要做解码,响应到客户端做编码
        pipeline.addLast("HttpServerCodec",new HttpServerCodec());

        //添加自定义的助手类,返回"hello netty~"
        pipeline.addLast("customHandler",new CustomHandler());

    }
}

复制代码
//创建自定义助手类
//SimpleChannelInboundHandler:对于请求来讲,相当于【入栈,出栈】
public class CustomHandler extends SimpleChannelInboundHandler<HttpObject> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpObject httpObject) throws Exception {
//        获取channel
        Channel channel=ctx.channel();

        if(httpObject instanceof HttpRequest){
            //        显示客户端的远程地址
            System.out.println(channel.remoteAddress());

//        copiedBuffer在JVM中创建一块缓冲区适用于深拷贝缓冲区的
            ByteBuf  content= Unpooled.copiedBuffer("Hello chenhao~", CharsetUtil.UTF_8);


//        创建一个http response
            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);
        }
        }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channel...注册");
        super.channelRegistered(ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channel...移除");
        super.channelUnregistered(ctx);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channel...活跃");
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channel...不活跃");
        super.channelInactive(ctx);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channel读取完毕...");
        super.channelReadComplete(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        System.out.println("channel用户事件触发...");
        super.userEventTriggered(ctx, evt);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        System.out.println("channel可写更改...");
        super.channelWritabilityChanged(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println("捕获到异常");
        super.exceptionCaught(ctx, cause);
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        System.out.println("助手类添加");
        super.handlerAdded(ctx);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("助手类移除");
        super.handlerRemoved(ctx);
    }
}

复制代码

原文 

https://juejin.im/post/5e2286195188252c3000285d

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 基于Netty的通信服务端编写

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址