powerfun-new-net/Program.cs

167 lines
6.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
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<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);
}
}
}
}
}