package com.cm.central.control.socket;

import com.cm.central.control.config.properties.SocketServerProperties;
import com.cm.central.control.handler.SocketServerChannelInitializer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: CentralControllerSocketServer
 * @Description: 中控socket server
 * @Author: WangGeng
 * @Date: 2020/7/28 1:39 下午
 * @Version: 1.0
 **/
@Component
public class SocketServerRunnable implements Runnable {

    private static final Logger LOG = LoggerFactory.getLogger(SocketServerRunnable.class);
    private ServerBootstrap serverBootstrap;

    @Autowired
    private SocketServerProperties socketServerProperties;
    @Autowired
    private SocketServerChannelInitializer socketServerChannelInitializer;

    @Override
    public void run() {
        if (serverBootstrap != null) {
            return;
        }
        serverBootstrap = new ServerBootstrap();
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup childGroup = new NioEventLoopGroup();
        try {
            serverBootstrap.group(bossGroup, childGroup);
            serverBootstrap.channel(NioServerSocketChannel.class);
            // 允许最大连接数
            serverBootstrap.option(ChannelOption.SO_BACKLOG, socketServerProperties.getSoBacklog());
            // 允许重复使用端口
            serverBootstrap.option(ChannelOption.SO_REUSEADDR, true);
            // 开启心跳保活机制，连接建立后，2小时左右没有数据传输激活
            serverBootstrap.option(ChannelOption.SO_KEEPALIVE, true);
            // 有数据就立即发送
            serverBootstrap.option(ChannelOption.TCP_NODELAY, true);
            serverBootstrap.option(ChannelOption.SO_SNDBUF, 1024 * 1024 * 1024);
            serverBootstrap.option(ChannelOption.SO_RCVBUF, 1024 * 1024 * 1024);
            serverBootstrap.childHandler(socketServerChannelInitializer);

            // 启动服务
            ChannelFuture channelFuture = serverBootstrap.bind(socketServerProperties.getPort()).sync().addListener(listener -> {
                if (listener.isSuccess()) {
                    StringBuilder socketOutSB = new StringBuilder();
                    socketOutSB.append("******************************\n");
                    socketOutSB.append("**                          **\n");
                    socketOutSB.append("**   CENTRAL SOCKET SERVER  **\n");
                    socketOutSB.append("**    START SUCCESSFULLY!   **\n");
                    socketOutSB.append("**                          **\n");
                    socketOutSB.append("**        PORT: " + socketServerProperties.getPort() + "        **\n");
                    socketOutSB.append("**                          **\n");
                    socketOutSB.append("******************************\n");
                    System.out.println(socketOutSB.toString());
                }
            });
            // 监听通道关闭
            channelFuture.channel().closeFuture().sync();
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        } finally {
            bossGroup.shutdownGracefully();
            childGroup.shutdownGracefully();
        }
    }
}
