package com.ym.im.core;

import com.ym.im.config.NettyConfig;
import com.ym.im.entity.NettyConstant;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * netty服务端启动类
 *
 * @author: JJww
 * @Date:2019-01-15
 */
@Slf4j
@Component
public class NettyServer {

    @Value("${netty.port}")
    private int port;

    @Autowired
    @Qualifier("bossGroup")
    private NioEventLoopGroup bossGroup;

    @Autowired
    @Qualifier("workerGroup")
    private NioEventLoopGroup workerGroup;

    @Autowired
    private WebSocketChannelInitializer webSocketChannelInitializer;

    @PostConstruct
    public void start() throws InterruptedException {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap.option(ChannelOption.SO_BACKLOG, NettyConstant.MAX_THREADS);//设置线程数
        serverBootstrap.group(bossGroup, workerGroup)//绑定线程池
                .channel(NioServerSocketChannel.class)//NioServerSocketChannel基于TCP协议的数据处理
                .localAddress(port)  // 绑定监听端口
                .childOption(ChannelOption.TCP_NODELAY, true)//立即写出
                .childOption(ChannelOption.SO_KEEPALIVE, true)//长连接
                .childHandler(webSocketChannelInitializer); // 添加处理器
        ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
        if (channelFuture.isSuccess()) {
            log.info("客服服务 启动完毕,IP:{}", port);
        }
    }


    @PreDestroy
    public void destroy() {
        bossGroup.shutdownGracefully().syncUninterruptibly();
        workerGroup.shutdownGracefully().syncUninterruptibly();
        log.info("客服服务 已关闭,IP:{}", port);
    }
}
