using OnlineUserPool.Hander; using OnlineUserPool.Model; using OnlineUserPool.Unility; using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace OnlineUserPool { class Program { private static IPEndPoint serverIpEndPoint; private static UdpClient udpServer; private static List clients = new List(); private static List receiveMes = new List(); private static object locker = new object(); public static System.Timers.Timer timer; private static MapRecordRankingHander mapRecordRankingHander; static void Main(string[] args) { Console.WriteLine(DateTime.Now.ToShortDateString()); Console.WriteLine("加载日志组件"); LogHelper.Init(); Log.Information("日志组件加载完成"); Log.Information("加载虚拟人物"); mapRecordRankingHander = new MapRecordRankingHander(); Log.Information("虚拟人物加载完成"); Log.Information($"初始化连接,当前地址:{ConfigHelp.Ip}:{ConfigHelp.Port}"); serverIpEndPoint = new IPEndPoint(IPAddress.Parse(ConfigHelp.Ip), ConfigHelp.Port); RunServer(); Log.Information("服务启动成功"); timer = new System.Timers.Timer(1000); timer.Elapsed += Timer_Elapsed; timer.AutoReset = true; timer.Start(); Log.Information("等待连接"); Console.ReadKey(); } private static void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { NotifyClient(); } private static void RunServer() { udpServer = new UdpClient(serverIpEndPoint.Port); uint IOC_IN = 0x80000000; uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; udpServer.Client.IOControl((int)SIO_UDP_CONNRESET, new byte[] { Convert.ToByte(false) }, null); var remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); Task.Run(() => { while (true) { try { byte[] receiveBytes = udpServer.Receive(ref remoteIpEndPoint); var returnData = Encoding.ASCII.GetString(receiveBytes); var msg = Newtonsoft.Json.JsonConvert.DeserializeObject(returnData); lock (locker) { receiveMes.Add(msg); #if DEBUG Console.WriteLine($"本次接收:{ remoteIpEndPoint.Address.ToString() }:{ remoteIpEndPoint.Port }收到消息:{ returnData }"); #endif if (!clients.Any(c => c.Equals(remoteIpEndPoint))) { clients.Add(new HostModel { IPEndPoint = remoteIpEndPoint, LastActiveTime = DateTime.Now, RouteId = msg.RouteId, MemberId = msg.MemberId, ShowVirtual = msg.ShowVirtual }); } else { if (msg.CommandType == 0) { var client = clients.FirstOrDefault(n => n.Equals(remoteIpEndPoint)); client.LastActiveTime = DateTime.Now; client.ShowVirtual = msg.ShowVirtual; } } //if (timer.AutoReset == false) //{ // timer.AutoReset = true; //} } } catch (Exception e) { Log.Error("RunServer:" + e.Message); } } }); } private static void NotifyClient() { try { lock (locker) { //加入虚拟人物消息 var virtualData = mapRecordRankingHander.GetVirtualUserData(); Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "-当前在线人数:" + clients.Count + "-当前虚拟人数:" + virtualData.Count); #if DEBUG Console.WriteLine($"在线人:{Newtonsoft.Json.JsonConvert.SerializeObject(receiveMes)}\r\n虚拟人:{Newtonsoft.Json.JsonConvert.SerializeObject(virtualData)}"); #endif receiveMes.AddRange(virtualData); SendMessage(clients, receiveMes); //移除下线的客户端 for (int i = 0; i < receiveMes.Count; i++) { if (receiveMes[i].exit && !receiveMes[i].IsVirtual)//客户端退出,并且不是虚拟的人物 { //这个地方有严重的逻辑错误(虚拟的人物不能和真实的人用同一个名字) var index = clients.FindIndex(n => n.MemberId == receiveMes[i].MemberId); if (index > -1) { clients.RemoveAt(index); } } } receiveMes.Clear();//删除已经发送的数据 clients.RemoveAll(i => i.Expire);//移除5钟内连接不上的客户端 } //更新虚拟人物信息 mapRecordRankingHander.RemoveEndAndAddNewVirtualUser(); } catch (Exception e) { Log.Error("NotifyClient:" + e.Message); } } private static void SendMessage(List clients, List msgModels) { string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(msgModels); var data = Encoding.ASCII.GetBytes(jsonString); foreach (var item in clients) { try { udpServer.Send(data, data.Length, item.IPEndPoint); } catch (Exception e) { Log.Error(item.IPEndPoint.ToString() + ":" + e.Message); } } } } }