diff --git a/App.xaml b/App.xaml new file mode 100644 index 0000000..308452b --- /dev/null +++ b/App.xaml @@ -0,0 +1,10 @@ + + + + + diff --git a/App.xaml.cs b/App.xaml.cs new file mode 100644 index 0000000..6f5932e --- /dev/null +++ b/App.xaml.cs @@ -0,0 +1,30 @@ +using OnlineUserPool.Views; +using Prism.Ioc; +using Prism.Unity; +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace OnlineUserPool +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : PrismApplication + { + protected override Window CreateShell() + { + var w = Container.Resolve(); + return w; + } + + protected override void RegisterTypes(IContainerRegistry containerRegistry) + { + //throw new NotImplementedException(); + } + } +} diff --git a/Hander/MapRecordRankingHander.cs b/Hander/MapRecordRankingHander.cs index 4dc4769..3cf89c0 100644 --- a/Hander/MapRecordRankingHander.cs +++ b/Hander/MapRecordRankingHander.cs @@ -52,7 +52,7 @@ namespace OnlineUserPool.Hander exit = item.End, IsCompleted = item.End, MemberId = -item.UserId,//虚拟的人Id变为负数 - Point = new double[] { targetData._Lat, targetData._Lon }, + Point = new double[] { Math.Round(targetData._Lat, 6), Math.Round(targetData._Lon, 6) }, Prop = string.Join(',', prop), RouteId = item.RouteId, EndDistance = targetData._Distance, diff --git a/Model/HostModel.cs b/Model/HostModel.cs index 4457544..054102e 100644 --- a/Model/HostModel.cs +++ b/Model/HostModel.cs @@ -1,15 +1,24 @@ -using System; +using Prism.Mvvm; +using System; using System.Collections.Generic; using System.Net; using System.Text; namespace OnlineUserPool.Model { - public class HostModel + public class HostModel : BindableBase { public IPEndPoint IPEndPoint { get; set; } - public DateTime LastActiveTime { get; set; } + private DateTime _LastActiveTime; + public DateTime LastActiveTime { + get { + return _LastActiveTime; + } + set { + SetProperty(ref _LastActiveTime, value); + } + } /// /// 地图编号 /// diff --git a/OnlineUserPool.csproj b/OnlineUserPool.csproj index db88e20..8455ce9 100644 --- a/OnlineUserPool.csproj +++ b/OnlineUserPool.csproj @@ -1,12 +1,14 @@ - + - Exe + WinExe netcoreapp3.1 + true - + + diff --git a/OnlineUserPool.csproj.user b/OnlineUserPool.csproj.user new file mode 100644 index 0000000..e195094 --- /dev/null +++ b/OnlineUserPool.csproj.user @@ -0,0 +1,19 @@ + + + + true + + + + Code + + + + + Designer + + + Designer + + + \ No newline at end of file diff --git a/Program.cs b/Program.cs deleted file mode 100644 index f0bfb8a..0000000 --- a/Program.cs +++ /dev/null @@ -1,166 +0,0 @@ -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 clients = new List(); - private static List receiveMes = new List(); - 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(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 clients, List 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); - } - } - } - } -} diff --git a/Unility/LogHelper.cs b/Unility/LogHelper.cs index 7a32737..907bbdf 100644 --- a/Unility/LogHelper.cs +++ b/Unility/LogHelper.cs @@ -11,7 +11,7 @@ namespace OnlineUserPool.Unility public static void Init() { string path = AppDomain.CurrentDomain.BaseDirectory+ "\\logs\\log.txt"; - Console.WriteLine(path); + //Console.WriteLine(path); Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().WriteTo.File(path, rollingInterval: RollingInterval.Day).CreateLogger(); } } diff --git a/ViewModels/MainWindowViewModel.cs b/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..edbdf3a --- /dev/null +++ b/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,209 @@ +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 Clients { get; private set; } = new ObservableCollection(); + private static List receiveMes = new List(); + private static object locker = new object(); + public static System.Timers.Timer timer; + private static MapRecordRankingHander mapRecordRankingHander; + + private Dispatcher dispatcher; + public ObservableCollection Customers { get; private set; } = + new ObservableCollection(); + + + public MainWindowViewModel() + { + 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(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) + { + 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) + { + Log.Error("NotifyClient:" + e.Message); + } + } + + private static void SendMessage(Collection clients, List 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); + } + } + } + + + void WriteLine(string str) + { + Debug.WriteLine(str); + } + } +} diff --git a/Views/MainWindow.xaml b/Views/MainWindow.xaml new file mode 100644 index 0000000..5fecdc9 --- /dev/null +++ b/Views/MainWindow.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/Views/MainWindow.xaml.cs b/Views/MainWindow.xaml.cs new file mode 100644 index 0000000..2d59ce2 --- /dev/null +++ b/Views/MainWindow.xaml.cs @@ -0,0 +1,44 @@ +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.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace OnlineUserPool.Views +{ + /// + /// MainWindow.xaml 的交互逻辑 + /// + public partial class MainWindow : Window + { + + + public MainWindow() + { + InitializeComponent(); + + this.Loaded += MainWindow_Loaded; + } + + private void MainWindow_Loaded(object sender, RoutedEventArgs e) + { + + } + + + } +}