package com.skr.mdm.netty;

import com.skr.mdm.util.SSLUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import java.io.File;
import java.util.concurrent.TimeUnit;

/**
 * @author nfq
 * @date 2020/7/24 16:08
 */
@Component
public class ChannelInitializerHandler extends ChannelInitializer {

    @Autowired
    private WebsocketHandler websocketHandler;

    @Override
    protected void initChannel(Channel ch) throws Exception {
        String keyPath = "key" + File.separator + "mdm.keystore";
        SSLContext sslContext = SSLUtil.createSSLContext("JKS", keyPath, "tkmdm999");
        // SSLEngine 此类允许使用ssl安全套接层协议进行安全通信
        SSLEngine engine = sslContext.createSSLEngine();
        // 使用服务端模式
        engine.setUseClientMode(false);
        // 验证客户端
        engine.setNeedClientAuth(true);
        ch.pipeline()
                .addLast(new SslHandler(engine))
                // HttpRequestDecoder和HttpResponseEncoder的一个组合，针对http协议进行编解码
                .addLast(new HttpServerCodec())
                // 将HttpMessage和HttpContents聚合到一个完成的 FullHttpRequest或FullHttpResponse中,具体是FullHttpRequest对象还是FullHttpResponse对象取决于是请求还是响应
                // 需要放到HttpServerCodec这个处理器后面
                .addLast(new HttpObjectAggregator(512 * 1024))
                // 分块向客户端写数据，防止发送大文件时导致内存溢出
                .addLast(new ChunkedWriteHandler())
                // 心跳机制
                .addLast(new IdleStateHandler(180, 120, 60, TimeUnit.SECONDS))
                .addLast(websocketHandler);
    }
}