package com.cm.central.control.client.socket.socket;

import com.cm.central.control.client.socket.config.properties.SocketClientProperties;
import com.cm.central.control.client.socket.handler.SocketClientChannelInitializer;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: SocketClient
 * @Description: Socket客户端
 * @Author: WangGeng
 * @Date: 2020/7/29 10:29 上午
 * @Version: 1.0
 **/
@Component
public class SocketClientRunnable implements Runnable, InitializingBean {

    private static final Logger LOG = LoggerFactory.getLogger(SocketClientRunnable.class);
    @Autowired
    private SocketClientProperties socketClientProperties;
    @Autowired
    private SocketClientChannelInitializer socketClientChannelInitializer;
    private Bootstrap bootstrap = new Bootstrap();
    private EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

    @Override
    public void afterPropertiesSet() throws Exception {
        bootstrap.group(eventLoopGroup);
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
        bootstrap.option(ChannelOption.SO_SNDBUF, 1024 * 1024 * 1024);
        bootstrap.option(ChannelOption.SO_RCVBUF, 1024 * 1024 * 1024);
        bootstrap.handler(socketClientChannelInitializer);
    }

    @Override
    public void run() {
        try {
            ChannelFuture channelFuture = bootstrap.connect(socketClientProperties.getHost(), socketClientProperties.getPort());
            channelFuture.addListener((ChannelFutureListener) future -> {
                if (!future.isSuccess()) {
                    future.channel().pipeline().fireChannelInactive();
                }
            });
            channelFuture.channel().closeFuture();
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
        }
    }
}
