package cn.component.message.udp;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.NetUtil;
import org.springframework.beans.factory.annotation.Autowired;
import cn.util.core.LogKit;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author BJTU
 * @Deprecated UDP组播服务器
 */
public class GroupServer 
{
	@Autowired
	GroupServerHandler groupServerHandler;
	
	private final AtomicInteger threadNumber = new AtomicInteger(1);
	ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 10, 60,
			TimeUnit.SECONDS, new SynchronousQueue<Runnable>()
			, r -> new Thread(r, "GroupServer-Thread-" + threadNumber.getAndIncrement()));

	public void start(InetSocketAddress groupAddress) {
		try {
			executor.execute(() -> {
				//System.setProperty("java.net.preferIPv4Stack", "true");//只使用IPV4
				EventLoopGroup group = new NioEventLoopGroup();
				try {
					NetworkInterface ni = NetUtil.LOOPBACK_IF;
					InetAddress localAddress = InetAddress.getByName("127.0.0.1");

					Bootstrap bootstrap = new Bootstrap();
					//设置NioDatagramChannel channel(NioDatagramChannel.class)
					bootstrap.group(group)
					.localAddress(localAddress, groupAddress.getPort())
					//                            .remoteAddress(InetAddress.getByName("192.168.0.200"),groupAddress.getPort())
					//                            .remoteAddress(InetAddress.getByName("127.0.0.1"),groupAddress.getPort())
					//设置Option 组播
					.option(ChannelOption.IP_MULTICAST_IF, ni)
					//设置Option 地址
					.option(ChannelOption.IP_MULTICAST_ADDR, localAddress)
					//设置地址
					.option(ChannelOption.SO_REUSEADDR, true)
					.handler(groupServerHandler)
					.channelFactory(new ChannelFactory<NioDatagramChannel>() {
						@Override
						public NioDatagramChannel newChannel() {
							// 指定协议簇为 IPv4
							return new NioDatagramChannel(InternetProtocolFamily.IPv4);
						}
					});
					LogKit.info("--------------Group服务端upd服务启动----------------");
					//获取NioDatagramChannel
					NioDatagramChannel channel = (NioDatagramChannel) bootstrap.bind(groupAddress.getPort()).sync().channel();
					//加入组
					channel.joinGroup(groupAddress, ni).sync();
					LogKit.info("Group服务器正在监听消息......");
					//关闭Channel
					channel.closeFuture().await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (UnknownHostException e) {
					throw new RuntimeException(e);
				} finally {
					group.shutdownGracefully();
				}
			});
		} catch (Exception e) {
			LogKit.info(e.toString());
		}
	}
}
