内存优化

This commit is contained in:
lishuo committed 2024-01-24 15:23:28 +08:00
1 parent 8f0845faaa
commit b07be239fd
6 files changed
+368 -202

No files matched your search

+197 -125
View File
@@ -29,11 +29,8 @@ namespace OnlineUserPool.ViewModels
private static object locker = new object();
public static System.Timers.Timer timer;
private static IHandle mapRecordRankingHander;
private Dispatcher dispatcher;
public ObservableCollection<MsgModel> Customers { get; private set; } =
new ObservableCollection<MsgModel>();
public ObservableCollection<MsgModel> Customers { get; private set; } = new ObservableCollection<MsgModel>();
private string _Title = "";
public string Title
{
@@ -72,7 +69,9 @@ namespace OnlineUserPool.ViewModels
SetProperty(ref _closeVirtualUser, value);
}
}
private const int ROOM_TIME_OUT = 60;
private const int TOTAL_PROCESS = 100;
//private IService _udpService;
public MainWindowViewModel()
@@ -87,15 +86,13 @@ namespace OnlineUserPool.ViewModels
//初测程序关闭事件
Application.Current.MainWindow.Closing += MainWindow_Closing;
Title = $"{ IPAddress.Any }:{ ConfigHelp.UdpPort }";
dispatcher = Dispatcher.CurrentDispatcher;
WriteLine(DateTime.Now.ToShortDateString());
LogHelper.Init();
mapRecordRankingHander = new MapRecordRankingHander();//
//mapRecordRankingHander = new MultiUserHandle();
Log.Information($"初始化连接,当前地址:{ IPAddress.Any }:{ConfigHelp.UdpPort}");
new TcpService().RunServer(ReceivedData, CientDisconnected);
new TcpService().RunServer(ReceivedData, ClientDisconnected);
var _udpService = new UdpService();
_udpService.RunServer(ReceivedData);
@@ -105,6 +102,18 @@ namespace OnlineUserPool.ViewModels
timer.AutoReset = true;
timer.Start();
Log.Information("等待连接");
ReleaseMemory();
}
private void ReleaseMemory()
{
var timers = new System.Timers.Timer(3333);
timers.Elapsed += (s, e) =>
{
GC.Collect();
};
timers.AutoReset = true;
timers.Start();
}
private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
@@ -151,16 +160,19 @@ namespace OnlineUserPool.ViewModels
{
var client = Clients.FirstOrDefault(n => n.Equals(remoteIpEndPoint));
var msg1 = (msg as MsgModel);
client.Competitionid = msg1.Competitionid;
client.Competitionid = msg1.CompetitionId;
client.Model = msg1.Model;
if (client.Model == "")
{
client.RoomId = msg1.RoomId;
}
if (msg1.V > 0)
{
client.V = msg1.V;
}
receiveMes.Add(msg1);
HandleGameRoomSaved(msg1);
}
@@ -184,15 +196,6 @@ namespace OnlineUserPool.ViewModels
HandleGameRoom(msg);
}
break;
default:
break;
}
if (msg.CommandType == 0)
{
//client.ShowVirtual = msg.ShowVirtual;
}
else if (msg.CommandType == 1)
{
}
});
}
@@ -208,6 +211,7 @@ namespace OnlineUserPool.ViewModels
GameRoomHelper.Set(RoomList.ToList());
}
}
private void HandleGameRoomSaved(MsgModel msg1)
{
//对战房间内的人保存处理
@@ -336,7 +340,7 @@ namespace OnlineUserPool.ViewModels
Point = new double[] { 0d, 0d },
});
var temp = string.Join("|", list.Where(m => m.Competitionid == needSend.Competitionid).Select(m => m.ToString(2))) + "|";
var temp = string.Join("|", list.Where(m => m.CompetitionId == needSend.Competitionid).Select(m => m.ToString(2))) + "|";
List<RoomModel> rooms;
if (!string.IsNullOrEmpty(query.Name))
{
@@ -547,8 +551,7 @@ namespace OnlineUserPool.ViewModels
SendGameRoomMessage(room);
}
}
private const int ROOM_TIME_OUT = 60;
private const int TOTAL_PROCESS = 100;
//处理房间内人loading进度
private void HandleGameRoomProcess(ReceiveModel msg)
{
@@ -635,10 +638,6 @@ namespace OnlineUserPool.ViewModels
{
dispatcher.Invoke(() =>
{
//Customers.Clear();
//删除已经发送的数据
//receiveMes.Clear();
//移除5钟内连接不上的客户端
Clients.ToList().ForEach(item =>
{
@@ -650,67 +649,32 @@ namespace OnlineUserPool.ViewModels
});
return;
}
lock (locker)
{
var msgs = CloneJson(receiveMes).ToList();
receiveMes.Clear();
if (!CloseVirtualUser)
{
//加入虚拟人物消息
var virtualData = mapRecordRankingHander.GetVirtualUserData();
VirtualData = $"{virtualData.Count}";
WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "-当前在线人数:" + Clients.Count + "-当前虚拟人数:" + virtualData.Count);
#if DEBUG
WriteLine($"在线人:{Newtonsoft.Json.JsonConvert.SerializeObject(msgs)}");
//\r\n虚拟人:{Newtonsoft.Json.JsonConvert.SerializeObject(virtualData)}
#endif
msgs.AddRange(virtualData);
}
//屏蔽房间模式的用户
var c = Clients.Where(c => string.IsNullOrEmpty(c.Model)).ToList();
SendMessage(c, msgs);
dispatcher.Invoke(() =>
{
Customers.Clear();
foreach (var item in msgs)
var msgs = receiveMes.ToList();
//加入虚拟人物消息
if (!CloseVirtualUser)
{
if (Customers.Any(c => c.MemberId == item.MemberId))
{
continue;
}
Customers.Add(item);
var virtualData = mapRecordRankingHander.GetVirtualUserData();
VirtualData = $"{virtualData.Count}";
msgs.AddRange(virtualData);
}
//移除下线的客户端
for (int i = 0; i < msgs.Count; i++)
{
if (msgs[i].exit && msgs[i].MemberId > 0)//客户端退出,并且不是虚拟的人物
{
//这个地方有严重的逻辑错误(虚拟的人物不能和真实的人用同一个名字)
var info = Clients.FirstOrDefault(n => n.MemberId == msgs[i].MemberId);
if (info != null)
{
RemoveClient(info);
}
}
}
//删除已经发送的数据
//receiveMes.Clear();
//移除5钟内连接不上的客户端
Clients.ToList().ForEach(item =>
{
if (item.Expire)
{
RemoveClient(item);
}
});
//屏蔽房间模式的用户
var c = Clients.Where(c => string.IsNullOrEmpty(c.Model)).ToList();
SendMessage(c, msgs);
RemoveClientAdvanced(msgs);
AddCustomers(msgs);
receiveMes.Clear();
msgs.Clear();
msgs = null;
});
//更新虚拟人物信息
mapRecordRankingHander.RemoveEndAndAddNewVirtualUser(Clients.Count);
}
//更新虚拟人物信息
mapRecordRankingHander.RemoveEndAndAddNewVirtualUser(Customers.Count);
}
catch (Exception e)
{
@@ -718,52 +682,70 @@ namespace OnlineUserPool.ViewModels
}
}
private void SendMessage(IList<HostModel> clients, List<MsgModel> msgModels)
private void RemoveClientAdvanced(List<MsgModel> msgs)
{
if (!clients.Any() || !msgModels.Any())
//移除下线的客户端
for (int i = 0; i < msgs.Count; i++)
{
if (msgs[i].Exit && msgs[i].MemberId > 0)//客户端退出,并且不是虚拟的人物
{
//这个地方有严重的逻辑错误(虚拟的人物不能和真实的人用同一个名字)
var info = Clients.FirstOrDefault(n => n.MemberId == msgs[i].MemberId);
if (info != null)
{
RemoveClient(info);
}
}
}
//移除5钟内连接不上的客户端
Clients.ToList().ForEach(item =>
{
if (item.Expire)
{
RemoveClient(item);
}
});
}
private void AddCustomers(List<MsgModel> msgs)
{
foreach (var item in msgs)
{
var client = Clients.FirstOrDefault(c => c.MemberId == item.MemberId);
if (client == null)
{
Customers.Remove(item);
continue;
}
var customer = Customers.FirstOrDefault(c => c.MemberId == item.MemberId);
if (customer != null)
{
customer.Update(item);
}
else
{
Customers.Add(item);
}
}
}
private StringBuilder sb = new StringBuilder();
private void SendMessage(IList<HostModel> clients, List<MsgModel> list)
{
if (!clients.Any() || !list.Any())
{
return;
}
var clients1 = clients.ToList();
var list = CloneJson<List<MsgModel>>(msgModels);
foreach (var item in list)
{
item.PreDistance = Math.Round(item.PreDistance, 5);
item.EndDistance = Math.Round(item.EndDistance, 5);
item.WeightKg = Math.Round(item.WeightKg, 2);
}
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(list.Select(m => new {
m.RouteId,
m.MemberId,
m.Point,
m.IsCompleted,
m.exit,
m.Speed,
m.PreDistance,
m.EndDistance,
//m.IsVirtual,//后面要把这个字段过滤掉
m.WeightKg,
m.Competitionid,
m.Saved,
m.FrameRate,
}));
var data = Encoding.ASCII.GetBytes(jsonString);
var strV1 = string.Join("|", list.Select(m => m.ToString(1)));
if (!string.IsNullOrWhiteSpace(strV1))
{
strV1 += "|";
}
WriteLine(strV1);
WriteLine(strV1.Length.ToString());
var data1 = new NetworkData(strV1);
var data1ForUdp = new NetworkData(strV1.Last() == '|' ? strV1.Substring(0, strV1.Length - 1) : strV1);
SendDataSize = $"\t单客户端数据包V1:{ data1.GetBytes().Length / 1000D }KB,一共占用带宽:{ data1.GetBytes().Length / 1000D * clients1.Count }KB,压缩以后{ data1.GetBytes(true).Length / 1000D * clients1.Count }KB";
#region 发送数据
foreach (var item in clients1)
@@ -771,39 +753,73 @@ namespace OnlineUserPool.ViewModels
try
{
if (item == null) continue;
if (item.V != 1 && item.V != 2)
{
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(list.Select(m => new {
m.RouteId,
m.MemberId,
m.Point,
m.IsCompleted,
exit = m.Exit,
m.Speed,
m.PreDistance,
m.EndDistance,
//m.IsVirtual,//后面要把这个字段过滤掉
m.WeightKg,
Competitionid = m.CompetitionId,
m.Saved,
m.FrameRate,
}));
var data = Encoding.ASCII.GetBytes(jsonString);
item.Service.Send(data, data.Length, item.IPEndPoint);
data = null;
continue;
}
if (item.V == 1 && item.Service is UdpService)
{
sb.Clear();
foreach (var obj in list)
{
sb.Append(obj.ToString(1));
sb.Append("|");
}
var strV1 = sb.ToString();
var data1ForUdp = new NetworkData(strV1.Last() == '|' ? strV1.Substring(0, strV1.Length - 1) : strV1);
item.Service.Send(data1ForUdp.GetBytes(), data1ForUdp.GetBytes().Length, item.IPEndPoint);
data1ForUdp = null;
}
if(item.Service is TcpService)
{
NetworkData ddd = null;
NetworkData networkData = null;
if (item.V == 1)
{
ddd = data1;
sb.Clear();
foreach (var obj in list)
{
sb.Append(obj.ToString(1));
sb.Append("|");
}
var strV1 = sb.ToString();
var data1 = new NetworkData(strV1);
networkData = data1;
}
else if (item.V == 2)
{
var temp = string.Join("|", list.Where(m => m.Competitionid == item.Competitionid).Select(m => m.ToString(2))) + "|";
var watchList1 = string.Join('|', clients1.Where(c => c.IsWatch && c.Competitionid == item.Competitionid).Select(c => c.MemberId));
var e = string.Join("|", list.Where(c => c.RoomId > 0 || c.FrameRate > 0).Select(c => $"{c.MemberId},{c.RoomId},{c.FrameRate},{c.TotalTicks}"));
var strV21 = $"*l{{{ temp }}};w{{{ watchList1 }}};e{{{ e }}};#";
ddd = new NetworkData(strV21);
networkData = HandleGzipNetworkData(list,item);
}
else
{
continue;
}
bool isZip = item.Encoding == "gzip";
item.Service.Send(ddd.GetBytes(isZip), ddd.GetBytes(isZip).Length, item.IPEndPoint);
item.Service.Send(networkData.GetBytes(isZip), networkData.GetBytes(isZip).Length, item.IPEndPoint);
networkData = null;
}
}
catch (Exception e)
@@ -812,9 +828,63 @@ namespace OnlineUserPool.ViewModels
Log.Error($"{ item.IPEndPoint.ToString() }:{ e.Message }\r\n{ e.StackTrace }");
}
}
clients1 = null;
#endregion
}
private NetworkData HandleGzipNetworkData(List<MsgModel> list, HostModel item)
{
sb.Clear();
foreach (var obj in list.Where(m => m.CompetitionId == item.Competitionid).Select(m => m.ToString(2)))
{
sb.Append(obj);
sb.Append("|");
}
sb.Remove(sb.Length - 1, 1);
var temp = sb.ToString();
sb.Clear();
foreach (var obj in Clients.Where(c => c.IsWatch && c.Competitionid == item.Competitionid).Select(c => c.MemberId))
{
sb.Append(obj);
sb.Append("|");
}
if (sb.Length > 0)
{
sb.Remove(sb.Length - 1, 1);
}
var watchList1 = sb.ToString();
sb.Clear();
foreach (var c in list.Where(c => c.RoomId > 0 || c.FrameRate > 0))
{
sb.Append($"{c.MemberId},{c.RoomId},{c.FrameRate},{c.TotalTicks}");
sb.Append("|");
}
if (sb.Length > 0)
{
sb.Remove(sb.Length - 1, 1);
}
var e = sb.ToString();
sb.Clear();
sb.Append("*l{");
sb.Append(temp);
sb.Append("};w{");
sb.Append(watchList1);
sb.Append("};e{");
sb.Append(e);
sb.Append("};#");
var strV2 = sb.ToString();
var data2 = new NetworkData(strV2);
return data2;
}
private void GameRoomDisConnectHandler(HostModel client)
{
////如果是在对战房间或者对战列表掉线执行,骑行阶段断开连接不移除房间信息
@@ -828,15 +898,16 @@ namespace OnlineUserPool.ViewModels
o.List.Remove(needRemove);
}
});
var needRemoveList = RoomList.ToList().Where(c => c.List.Count == 0 && c.Status != 2).ToList();
foreach (var item in needRemoveList)
{
RoomList.Remove(item);
}
BroadCastGameRoomList();
}
void WriteLine(string str)
{
//Debug.WriteLine(str);
@@ -859,7 +930,7 @@ namespace OnlineUserPool.ViewModels
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
}
private void CientDisconnected(EndPoint point)
private void ClientDisconnected(EndPoint point)
{
dispatcher.Invoke(() =>
{
@@ -874,7 +945,7 @@ namespace OnlineUserPool.ViewModels
}
catch(Exception ex)
{
Log.Information("在CientDisconnected触发以后,删除client时报错了,"+ ex.Message +", " + ex.StackTrace);
Log.Information("在ClientDisconnected触发以后,删除client时报错了,"+ ex.Message +", " + ex.StackTrace);
}
});
}
@@ -883,6 +954,7 @@ namespace OnlineUserPool.ViewModels
{
BeforeRemoved(client);
Clients.Remove(client);
Customers.Clear();
}
private void BeforeRemoved(HostModel client)