package com.sjyt.icom.asst.server;

import com.sjyt.icom.asst.conf.properties.WebSocketProperties;
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.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Netty服务器配置
 *
 * @author renyanru
 * @version V1.0.0
 * @date 2022/5/27 10:12
 */
@Slf4j
@Component
@AllArgsConstructor
public class NettyServer {
   private final WebSocketProperties webSocketProperties;
   private final NioWebSocketChannelInitializer nioWebSocketChannelInitializer;

  public void start() throws Exception {
    NioEventLoopGroup bossGroup = new NioEventLoopGroup(webSocketProperties.getBossThread());
    NioEventLoopGroup workerGroup = new NioEventLoopGroup(webSocketProperties.getWorkerThread());
    ChannelFuture channelFuture = null;
    try {
      ServerBootstrap sb = new ServerBootstrap();
      // 设置线程队列得到连接个数
      sb.option(ChannelOption.SO_BACKLOG, webSocketProperties.getBacklog());
      // 设置保持活动连接状态
      sb.childOption(ChannelOption.SO_KEEPALIVE, true);
      sb.group(bossGroup, workerGroup) // 绑定线程池
          .channel(NioServerSocketChannel.class) // 指定使用的channel
          .localAddress(webSocketProperties.getPort()) // 绑定监听端口
          .childHandler(nioWebSocketChannelInitializer);
      ChannelFuture cf = sb.bind().sync(); // 服务器异步创建绑定
      System.out.println(NettyServer.class + " 启动正在监听： " + cf.channel().localAddress());
      channelFuture = cf.channel().closeFuture().sync(); // 关闭服务器通道
    } finally {
      if (channelFuture != null && channelFuture.isSuccess()) {
        log.info(
            "Netty服务器在端口上启动: {} (websocket) with context path '{}'",
            webSocketProperties.getPort(),
            webSocketProperties.getPath());
      } else {
        log.error("Netty服务器启动失败.");
        bossGroup.shutdownGracefully().sync();
        workerGroup.shutdownGracefully().sync();
      }
    }
  }
}
