package com.yfd.platform.component.nettyserver;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.timeout.ReadTimeoutHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.ByteOrder;

import static java.nio.ByteOrder.LITTLE_ENDIAN;

/**
 * netty服务器，主要用于与客户端通讯
 */

public class NettyServer {
    private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);
    //    private static final int MAX_FRAME_LENGTH = 1024 * 1024 * 1024;   // 设置最大消息长度
    private static final byte[] DELIMITER = {(byte) 0xEB, (byte) 0x90};
    private static final int MAX_FRAME_LENGTH = Integer.MAX_VALUE;  //最大长度
    private static final int LENGTH_FIELD_OFFSET = 19;  //长度偏移
    private static final int LENGTH_FIELD_LENGTH = 4;  //长度字段所占的字节数
    private static final int LENGTH_ADJUSTMENT = 0;
    private static final int INITIAL_BYTES_TO_STRIP = 0;
    private final int port; //监听端口
    public NettyServer(int port) {
        this.port = port;
    }


    public void run() throws Exception {
        //创建两个线程组
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup(); //8个NioEventLoop

        try {
            ServerBootstrap b = new ServerBootstrap();

            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            //获取到pipeline
                            ChannelPipeline pipeline = ch.pipeline();
                            //向pipeline加入编码器
                            pipeline.addLast("encoder", new MyMessageEncoder());
                            //向pipeline加入解码器
                            pipeline.addLast(new MyDelimiterBasedFrameDecoder(MAX_FRAME_LENGTH,
                                    Unpooled.wrappedBuffer(DELIMITER)));
                            pipeline.addLast(new MyLengthFieldBasedFrameDecoder(MAX_FRAME_LENGTH, LENGTH_FIELD_OFFSET
                                    , LENGTH_FIELD_LENGTH, LENGTH_ADJUSTMENT, INITIAL_BYTES_TO_STRIP, false));
                            //                            pipeline.addLast("decoder", new MyMessageDecoder());
                            //加入自己的业务处理handler
                            pipeline.addLast(new NettyServerHandler());
//                            pipeline.addLast(new ReadTimeoutHandler(60));

                        }
                    });
            logger.info("Netty TCP server is started!（port:" + port + "）");
            ChannelFuture channelFuture = b.bind(port).sync();
            //监听关闭
            channelFuture.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
