2020-10-13 08:54:24 +08:00
|
|
|
|
using Prism.Mvvm;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using OnlineUserPool.Hander;
|
|
|
|
|
|
using OnlineUserPool.Model;
|
|
|
|
|
|
using OnlineUserPool.Unility;
|
|
|
|
|
|
using Serilog;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Net;
|
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Windows.Threading;
|
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
|
|
|
|
|
|
|
namespace OnlineUserPool.ViewModels
|
|
|
|
|
|
{
|
|
|
|
|
|
public class MainWindowViewModel : BindableBase
|
|
|
|
|
|
{
|
|
|
|
|
|
private static IPEndPoint serverIpEndPoint;
|
|
|
|
|
|
private static UdpClient udpServer;
|
|
|
|
|
|
public ObservableCollection<HostModel> Clients { get; private set; } = new ObservableCollection<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;
|
|
|
|
|
|
|
|
|
|
|
|
private Dispatcher dispatcher;
|
|
|
|
|
|
public ObservableCollection<MsgModel> Customers { get; private set; } =
|
|
|
|
|
|
new ObservableCollection<MsgModel>();
|
|
|
|
|
|
|
2020-10-27 10:20:47 +08:00
|
|
|
|
private string _Title = "";
|
|
|
|
|
|
public string Title
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _Title; }
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
SetProperty(ref _Title, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-10-13 08:54:24 +08:00
|
|
|
|
|
|
|
|
|
|
public MainWindowViewModel()
|
|
|
|
|
|
{
|
2020-10-27 10:20:47 +08:00
|
|
|
|
Title = $"{ ConfigHelp.Ip }:{ ConfigHelp.Port }";
|
|
|
|
|
|
|
2020-10-13 08:54:24 +08:00
|
|
|
|
dispatcher = Dispatcher.CurrentDispatcher;
|
|
|
|
|
|
|
|
|
|
|
|
//Customers.Add("suntao");
|
|
|
|
|
|
WriteLine(DateTime.Now.ToShortDateString());
|
|
|
|
|
|
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 void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
NotifyClient();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private 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)
|
|
|
|
|
|
{
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
WriteLine($"本次接收:{ remoteIpEndPoint.Address.ToString() }:{ remoteIpEndPoint.Port }收到消息:{ returnData }");
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(msg.CommandType == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
receiveMes.Add(msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
//if (timer.AutoReset == false)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// timer.AutoReset = true;
|
|
|
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
|
|
|
|
|
Log.Error("RunServer:" + e.Message);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void NotifyClient()
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
lock (locker)
|
|
|
|
|
|
{
|
|
|
|
|
|
//加入虚拟人物消息
|
|
|
|
|
|
var virtualData = mapRecordRankingHander.GetVirtualUserData();
|
|
|
|
|
|
WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "-当前在线人数:" + Clients.Count + "-当前虚拟人数:" + virtualData.Count);
|
|
|
|
|
|
#if DEBUG
|
|
|
|
|
|
WriteLine($"在线人:{Newtonsoft.Json.JsonConvert.SerializeObject(receiveMes)}");
|
|
|
|
|
|
//\r\n虚拟人:{Newtonsoft.Json.JsonConvert.SerializeObject(virtualData)}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
receiveMes.AddRange(virtualData);
|
|
|
|
|
|
|
|
|
|
|
|
SendMessage(Clients, receiveMes);
|
|
|
|
|
|
|
|
|
|
|
|
dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Customers.Clear();
|
|
|
|
|
|
foreach (var item in receiveMes)
|
|
|
|
|
|
{
|
2020-10-27 10:20:47 +08:00
|
|
|
|
if (Customers.Any(c => c.MemberId == item.MemberId))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2020-10-13 08:54:24 +08:00
|
|
|
|
Customers.Add(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//移除下线的客户端
|
|
|
|
|
|
for (int i = 0; i < receiveMes.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (receiveMes[i].exit && !receiveMes[i].IsVirtual)//客户端退出,并且不是虚拟的人物
|
|
|
|
|
|
{
|
|
|
|
|
|
//这个地方有严重的逻辑错误(虚拟的人物不能和真实的人用同一个名字)
|
|
|
|
|
|
var info = Clients.FirstOrDefault(n => n.MemberId == receiveMes[i].MemberId);
|
|
|
|
|
|
if (info != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
Clients.Remove(info);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
receiveMes.Clear();//删除已经发送的数据
|
|
|
|
|
|
//clients.RemoveAll(i => i.Expire);//移除5钟内连接不上的客户端
|
|
|
|
|
|
Clients.ToList().ForEach(item =>
|
|
|
|
|
|
{
|
|
|
|
|
|
if (item.Expire)
|
|
|
|
|
|
{
|
|
|
|
|
|
Clients.Remove(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
//更新虚拟人物信息
|
|
|
|
|
|
mapRecordRankingHander.RemoveEndAndAddNewVirtualUser();
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
2020-10-27 10:20:47 +08:00
|
|
|
|
Log.Error($"NotifyClient:{ e.Message }\r\n{ e.StackTrace }");
|
2020-10-13 08:54:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static void SendMessage(Collection<HostModel> clients, List<MsgModel> msgModels)
|
|
|
|
|
|
{
|
2020-12-01 10:13:53 +08:00
|
|
|
|
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(msgModels.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
|
|
|
|
|
|
}));
|
2020-10-13 08:54:24 +08:00
|
|
|
|
var data = Encoding.ASCII.GetBytes(jsonString);
|
|
|
|
|
|
foreach (var item in clients)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
udpServer.Send(data, data.Length, item.IPEndPoint);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
2020-10-27 10:20:47 +08:00
|
|
|
|
Log.Error($"{ item.IPEndPoint.ToString() }:{ e.Message }\r\n{ e.StackTrace }");
|
2020-10-13 08:54:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void WriteLine(string str)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.WriteLine(str);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|