package com.docus.server.common.netty.server;

import com.docus.server.common.netty.Payload;
import com.docus.server.common.netty.server.handler.NettyBusinessHandler;
import com.docus.server.common.netty.server.handler.NettyHeartbeatHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * netty服务端信道初始化
 */
@Component
public class NettyServerInitializer extends ChannelInitializer<Channel> {

    @Resource
    private NettyServerProperties serverProperties;

    @Resource
    private NettyBusinessHandler businessHandler;

    @Resource
    private ChannelRepository channelRepository;

    @Override
    protected void initChannel(Channel channel) throws Exception {
        channel.pipeline()
            //空闲检测
            .addLast(new IdleStateHandler(serverProperties.getReaderIdleTimeSeconds(),
                serverProperties.getWriterIdleTimeSeconds(),
                serverProperties.getAllIdleTimeSeconds(),
                TimeUnit.SECONDS)
            )
            // 加载加码解码处理器，同时解决粘包拆包问题
            .addLast(new ProtobufVarint32FrameDecoder())
            .addLast(new ProtobufDecoder(Payload.Message.getDefaultInstance()))
            .addLast(new ProtobufVarint32LengthFieldPrepender())
            .addLast(new ProtobufEncoder())
            // 加载业务处理器
            .addLast(new NettyHeartbeatHandler(channelRepository))
            .addLast(businessHandler);
    }
}
