powerfun-new-net/Program.cs

167 lines
6.8 KiB
C#
Raw Normal View History

2020-09-17 10:23:26 +08:00
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<HostModel> clients = new List<HostModel>();
private static List<MsgModel> receiveMes = new List<MsgModel>();
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<MsgModel>(returnData);
lock (locker)
{
receiveMes.Add(msg);
#if DEBUG
2020-09-17 10:23:26 +08:00
Console.WriteLine($"本次接收:{ remoteIpEndPoint.Address.ToString() }:{ remoteIpEndPoint.Port }收到消息:{ returnData }");
#endif
2020-09-17 10:23:26 +08:00
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
2020-09-17 10:23:26 +08:00
Console.WriteLine($"在线人:{Newtonsoft.Json.JsonConvert.SerializeObject(receiveMes)}\r\n虚拟人{Newtonsoft.Json.JsonConvert.SerializeObject(virtualData)}");
#endif
2020-09-17 10:23:26 +08:00
receiveMes.AddRange(virtualData);
SendMessage(clients, receiveMes);
//移除下线的客户端
for (int i = 0; i < receiveMes.Count; i++)
{
if (receiveMes[i].exit && !receiveMes[i].IsVirtual)//客户端退出,并且不是虚拟的人物
2020-09-17 10:23:26 +08:00
{
//这个地方有严重的逻辑错误(虚拟的人物不能和真实的人用同一个名字)
2020-09-17 10:23:26 +08:00
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();
2020-09-17 10:23:26 +08:00
}
catch (Exception e)
{
Log.Error("NotifyClient:" + e.Message);
}
}
private static void SendMessage(List<HostModel> clients, List<MsgModel> 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);
}
}
}
}
}