forked from powerfun/udpservice
内存优化
This commit is contained in:
1 parent
8f0845faaa
commit
b07be239fd
6 files changed
+368
-202
No files matched your search
+197
-125
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user