using System;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Collections.Generic;
using MultiDup;
namespace BattleRoom
{
    internal class Program
    {

        const int port = 6006;                                                        // 端口号（用来监听客户端连接的）  

        static void Main(string[] args)
        {
            selfTest();
            Console.WriteLine("开启监听......");
            Console.WriteLine("ctrl + c 退出程序......");

            InitServerPeer();

            Task.Run(WatchConnecting).Wait();                                                // 开启监听线程 

        }

        /// <summary>
        /// 初始化服务器间socket
        /// </summary>
        async static void InitServerPeer()
        {
            var port = 6005;                                                                // 连接本机的大厅服务端口            
            var endPoint = new IPEndPoint(IPAddress.Loopback, port);
            //var endPoint = new IPEndPoint(IPAddress.Parse("192.168.10.17"), port);
            var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                await client.ConnectAsync(endPoint);
            }
            catch (Exception ee)
            {
                Debug.WriteLine(ee.Message);
            }
            RoomManager.Instance.ServerPeer = new ServerPeer(client);                     // 给管理器的服务器间socket赋值
            RoomManager.Instance.ServerPeer.OnSocketDisconnected += () => { InitServerPeer(); };
        }

        static void selfTest()
        {
            var rdb = Redis.Ins.GetDatabase(0);
            Debug.Assert(rdb.StringSet("test", "wanggang" + DateTime.Now.ToString("yyyyMMddHHmmss")), "Redis读写失败!");
        }

        /// <summary>
        /// 监听客户端发来的请求  
        /// </summary>
        async static Task WatchConnecting()
        {
            IPAddress ip = IPAddress.Any;
            IPEndPoint ipe = new IPEndPoint(ip, port);                                  //将IP地址和端口号绑定到网络节点point上  

            //定义一个套接字用于监听客户端发来的消息，包含三个参数（IP4寻址协议，流式连接，Tcp协议）  
            Socket SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            SocketWatch.Bind(ipe);                                                      // 监听绑定的网络节点           
            SocketWatch.Listen(20);                                                     // 将套接字的监听队列长度限制为20    

            while (true)                                                                // 持续不断监听客户端发来的请求     
            {
                Socket connection;
                try
                {
                    connection = await SocketWatch.AcceptAsync();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);                                       // 提示套接字监听异常     
                    break;
                }

                RoomManager.Instance.OnNewPeerConnected(new Peer(connection));           // 有新客户端连入
            }
            SocketWatch.Close();                                                         // 结束监听socket
        }


    }
}

