转载

基于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
正文到此结束
Loading...