forked from powerfun/udpservice
一些功能调整
增加tcp协议支持; 增加模拟多用户的功能;
This commit is contained in:
parent
e8b6418aa6
commit
0e931a3ac9
@ -1,14 +1,12 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using OnlineUserPool.Model;
|
||||
|
||||
using OnlineUserPool.Unility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OnlineUserPool.Unility
|
||||
namespace OnlineUserPool.Api
|
||||
{
|
||||
public class BaseApi
|
||||
{
|
||||
@ -19,7 +17,7 @@ namespace OnlineUserPool.Unility
|
||||
httpClient.DefaultRequestHeaders.UserAgent.Add(new System.Net.Http.Headers.ProductInfoHeaderValue("OnlineUserPool", "1.0.0"));
|
||||
}
|
||||
|
||||
protected static async Task<T> PostAsync<T>(string url, object data)
|
||||
public static async Task<T> PostAsync<T>(string url, object data)
|
||||
{
|
||||
StringContent stringContent;
|
||||
if (data != null)
|
||||
@ -35,36 +33,11 @@ namespace OnlineUserPool.Unility
|
||||
return JsonConvert.DeserializeObject<T>(result);
|
||||
}
|
||||
|
||||
protected static async Task<T> GetAsync<T>(string url)
|
||||
public static async Task<T> GetAsync<T>(string url)
|
||||
{
|
||||
var response = await httpClient.GetAsync(ConfigHelp.Host + url, HttpCompletionOption.ResponseContentRead).ConfigureAwait(false);
|
||||
var result = await response.Content.ReadAsStringAsync();
|
||||
return JsonConvert.DeserializeObject<T>(result);
|
||||
}
|
||||
}
|
||||
public class WebService : BaseApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 从服务端获取记录信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<MapRecordRanking> GetRecordFileFromServer(List<long> id)
|
||||
{
|
||||
if (!id.Any())
|
||||
{
|
||||
return new List<MapRecordRanking>();
|
||||
}
|
||||
return PostAsync<JsonResult<List<MapRecordRanking>>>("MapRecord/GetRandomList", id).ConfigureAwait(false).GetAwaiter().GetResult().data;
|
||||
}
|
||||
|
||||
public static List<MapRouteAndUserQueryVM> GetMapRouteRandomRecord(int top, IEnumerable<int> routeIds)
|
||||
{
|
||||
var routeIdsStr = "";
|
||||
if(routeIds != null)
|
||||
{
|
||||
routeIdsStr = string.Join(",", routeIds);
|
||||
}
|
||||
return GetAsync<JsonResult<List<MapRouteAndUserQueryVM>>>($"MapRecord/GetRandomRankingUserRecord?top={ top }&routeIds={ routeIdsStr }").ConfigureAwait(false).GetAwaiter().GetResult().data;
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Api/Model/MultiUserModel.cs
Normal file
41
Api/Model/MultiUserModel.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using OnlineUserPool.Model;
|
||||
using OnlineUserPool.Unility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnlineUserPool.Api.Model
|
||||
{
|
||||
public class MultiUserModel
|
||||
{
|
||||
public List<User> users { get; set; }
|
||||
|
||||
public MapDataModel route { get; set; }
|
||||
|
||||
|
||||
public class User
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public string NickName { get; set; }
|
||||
|
||||
public string WxHeadImg { get; set; }
|
||||
|
||||
public double Weight { get; set; }
|
||||
|
||||
public User()
|
||||
{
|
||||
Speed = CommonHelper.GenerateRandomInteger(0, 30);
|
||||
|
||||
//Distance = CommonHelper.GenerateRandomInteger(0, 30)/1000D;
|
||||
}
|
||||
|
||||
|
||||
public double Speed {
|
||||
get;set;
|
||||
}
|
||||
|
||||
public double Distance { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Api/WebService.cs
Normal file
38
Api/WebService.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using OnlineUserPool.Model;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OnlineUserPool.Api
|
||||
{
|
||||
public class WebService : BaseApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 从服务端获取记录信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<MapRecordRanking> GetRecordFileFromServer(List<long> id)
|
||||
{
|
||||
if (!id.Any())
|
||||
{
|
||||
return new List<MapRecordRanking>();
|
||||
}
|
||||
return PostAsync<JsonResult<List<MapRecordRanking>>>("MapRecord/GetRandomList", id).ConfigureAwait(false).GetAwaiter().GetResult().data;
|
||||
}
|
||||
|
||||
public static List<MapRouteAndUserQueryVM> GetMapRouteRandomRecord(int top, IEnumerable<int> routeIds)
|
||||
{
|
||||
var routeIdsStr = "";
|
||||
if(routeIds != null)
|
||||
{
|
||||
routeIdsStr = string.Join(",", routeIds);
|
||||
}
|
||||
return GetAsync<JsonResult<List<MapRouteAndUserQueryVM>>>($"MapRecord/GetRandomRankingUserRecord?top={ top }&routeIds={ routeIdsStr }").ConfigureAwait(false).GetAwaiter().GetResult().data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,9 +2,8 @@
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="Host" value="http://192.168.0.97:5082/"/>
|
||||
<add key="Top" value="10"/>
|
||||
<add key="Top" value="0"/>
|
||||
<add key="ShowVirtualUser" value="true"/>
|
||||
<add key="Ip" value="192.168.0.97"/>
|
||||
<add key="Port" value="11000"/>
|
||||
</appSettings>
|
||||
</configuration>
|
||||
14
Hander/IHandle.cs
Normal file
14
Hander/IHandle.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using OnlineUserPool.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnlineUserPool.Hander
|
||||
{
|
||||
interface IHandle
|
||||
{
|
||||
List<MsgModel> GetVirtualUserData();
|
||||
|
||||
void RemoveEndAndAddNewVirtualUser(int customerCount);
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using OnlineUserPool.Model;
|
||||
using OnlineUserPool.Api;
|
||||
using OnlineUserPool.Model;
|
||||
using OnlineUserPool.Unility;
|
||||
|
||||
using Serilog;
|
||||
@ -10,11 +11,11 @@ using System.Text;
|
||||
|
||||
namespace OnlineUserPool.Hander
|
||||
{
|
||||
public class MapRecordRankingHander
|
||||
public class MapRecordRankingHander : IHandle
|
||||
{
|
||||
private static List<MapRecordRanking> mapRecordRankings;
|
||||
private static List<MapRecordRanking> mapRecordRankings = new List<MapRecordRanking>();
|
||||
private static object locker = new object();//防止服务端响应慢,多次加载
|
||||
private int top = ConfigHelp.Top;
|
||||
//private int top = ConfigHelp.Top;
|
||||
|
||||
public MapRecordRankingHander()
|
||||
{
|
||||
@ -23,13 +24,15 @@ namespace OnlineUserPool.Hander
|
||||
|
||||
private void Init()
|
||||
{
|
||||
var records = WebService.GetMapRouteRandomRecord(top, null);
|
||||
var pageSize = 10;
|
||||
var pageCount = (int)Math.Ceiling(records.Count / (double)pageSize);
|
||||
mapRecordRankings = new List<MapRecordRanking>();
|
||||
for (int i = 0; i < pageCount; i++)
|
||||
if (ConfigHelp.Top > 0)
|
||||
{
|
||||
mapRecordRankings.AddRange(WebService.GetRecordFileFromServer(records.Skip(i* pageSize).Take(pageSize).Select(n => n.Id).ToList()));
|
||||
var records = WebService.GetMapRouteRandomRecord(ConfigHelp.Top, null);
|
||||
var pageSize = 10;
|
||||
var pageCount = (int)Math.Ceiling(records.Count / (double)pageSize);
|
||||
for (int i = 0; i < pageCount; i++)
|
||||
{
|
||||
mapRecordRankings.AddRange(WebService.GetRecordFileFromServer(records.Skip(i * pageSize).Take(pageSize).Select(n => n.Id).ToList()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,9 +76,9 @@ namespace OnlineUserPool.Hander
|
||||
//Prop = string.Join(',', prop),
|
||||
RouteId = item.RouteId,
|
||||
EndDistance = Math.Round(targetData._Distance, 6),
|
||||
ShowVirtual = true,
|
||||
//ShowVirtual = true,
|
||||
CommandType = 1,
|
||||
IsVirtual = true,
|
||||
//IsVirtual = true,
|
||||
Speed = targetData._Speed,
|
||||
WeightKg = weightKg,
|
||||
PreDistance = item.GetPreDistance()
|
||||
@ -94,31 +97,31 @@ namespace OnlineUserPool.Hander
|
||||
/// <summary>
|
||||
/// 删除已经骑行完的人,添加新的人物进去
|
||||
/// </summary>
|
||||
public void RemoveEndAndAddNewVirtualUser()
|
||||
public void RemoveEndAndAddNewVirtualUser(int customerCount)
|
||||
{
|
||||
lock (locker)
|
||||
{
|
||||
var end = mapRecordRankings.FindAll(n => n.End);
|
||||
//if (end.Count == mapRecordRankings.Count)
|
||||
//{
|
||||
// Init();
|
||||
//}
|
||||
if (end.Count > 0)
|
||||
{
|
||||
var virutalEndCount = mapRecordRankings.Count(d => d.UserId < 0 && d.End);
|
||||
var routeIds = mapRecordRankings.Select(n => n.RouteId).Distinct().ToList();
|
||||
mapRecordRankings.RemoveAll(n => n.End);
|
||||
if (virutalEndCount > 0)
|
||||
{
|
||||
var randomUser = WebService.GetMapRouteRandomRecord(virutalEndCount, routeIds);
|
||||
mapRecordRankings.RemoveAll(n => n.End);
|
||||
//var virutalEndCount = mapRecordRankings.Count(d => d.UserId < 0 && d.End);
|
||||
var routeIds = mapRecordRankings.Select(n => n.RouteId).Distinct().ToList();
|
||||
|
||||
//var str = "参数:" + (ConfigHelp.Top - virutalEndCount) + "," + string.Join(",",routeIds) + "\r\n";
|
||||
//str += "服务端返回:" + Newtonsoft.Json.JsonConvert.SerializeObject(randomUser) +"\r\n";
|
||||
//Log.Information(str);
|
||||
var addRankings = WebService.GetRecordFileFromServer(randomUser.Select(n => n.Id).ToList());
|
||||
mapRecordRankings.AddRange(addRankings);
|
||||
}
|
||||
var top = ConfigHelp.Top;
|
||||
if(customerCount > 9)
|
||||
{
|
||||
top = 0;
|
||||
}
|
||||
if(top - mapRecordRankings.Count(d=>d.UserId<0) > 0)
|
||||
{
|
||||
var count = top - mapRecordRankings.Count(d => d.UserId < 0);
|
||||
var randomUser = WebService.GetMapRouteRandomRecord(count, routeIds);
|
||||
|
||||
//var str = "参数:" + (ConfigHelp.Top - virutalEndCount) + "," + string.Join(",",routeIds) + "\r\n";
|
||||
//str += "服务端返回:" + Newtonsoft.Json.JsonConvert.SerializeObject(randomUser) +"\r\n";
|
||||
//Log.Information(str);
|
||||
var addRankings = WebService.GetRecordFileFromServer(randomUser.Select(n => n.Id).ToList());
|
||||
mapRecordRankings.AddRange(addRankings);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
84
Hander/MultiUserHandle.cs
Normal file
84
Hander/MultiUserHandle.cs
Normal file
@ -0,0 +1,84 @@
|
||||
using OnlineUserPool.Api;
|
||||
using OnlineUserPool.Api.Model;
|
||||
using OnlineUserPool.Model;
|
||||
using OnlineUserPool.Unility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OnlineUserPool.Hander
|
||||
{
|
||||
public class MultiUserHandle : IHandle
|
||||
{
|
||||
private int _index = -1;
|
||||
private MultiUserModel model;
|
||||
private TurfHelper _turfHelper;
|
||||
private int _routeId = 4297; //1660;
|
||||
private int _size = 200;
|
||||
public MultiUserHandle()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public async void Init()
|
||||
{
|
||||
model = await BaseApi.GetAsync<MultiUserModel>($"/Map/sss?routeId={ _routeId }&size={ _size }");
|
||||
double i = 0;
|
||||
foreach (var item in model.users)
|
||||
{
|
||||
i += 0.0005;
|
||||
item.Distance = i;
|
||||
}
|
||||
_turfHelper = new TurfHelper(model.route.List.Select(d => d.Point));
|
||||
//Debug.WriteLine(res);
|
||||
}
|
||||
|
||||
public List<MsgModel> GetVirtualUserData()
|
||||
{
|
||||
_index++;
|
||||
|
||||
var msgModels = new List<MsgModel>();
|
||||
if(model == null)
|
||||
{
|
||||
return msgModels;
|
||||
}
|
||||
foreach (var item in model.users)
|
||||
{
|
||||
var preDistance = 0D;
|
||||
//item.Distance = CommonHelper.GenerateRandomInteger(0, 30) / 1000D;
|
||||
if (_index > 0)
|
||||
{
|
||||
preDistance = item.Distance * (_index -1);
|
||||
}
|
||||
var point = _turfHelper.Along(item.Distance * _index);
|
||||
var info = new MsgModel()
|
||||
{
|
||||
exit = false,
|
||||
IsCompleted = false,
|
||||
MemberId = item.Id,//虚拟的人Id变为负数
|
||||
Point = new double[] { Math.Round(point.Latitude, 6), Math.Round(point.Longitude, 6) },
|
||||
//Prop = string.Join(',', prop),
|
||||
RouteId = _routeId,
|
||||
EndDistance = item.Distance * _index,
|
||||
//ShowVirtual = true,
|
||||
CommandType = 1,
|
||||
//IsVirtual = true,
|
||||
Speed = item.Speed,
|
||||
WeightKg = 0,
|
||||
PreDistance = preDistance,
|
||||
Competitionid = 30
|
||||
};
|
||||
msgModels.Add(info);
|
||||
}
|
||||
|
||||
return msgModels;
|
||||
}
|
||||
|
||||
public void RemoveEndAndAddNewVirtualUser(int customerCount)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using Prism.Mvvm;
|
||||
using OnlineUserPool.Services;
|
||||
using Prism.Mvvm;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
@ -50,9 +51,26 @@ namespace OnlineUserPool.Model
|
||||
/// </summary>
|
||||
public List<int> ShowRouteId { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 是否展示在线的人
|
||||
///// </summary>
|
||||
//public bool ShowVirtual { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否展示在线的人
|
||||
/// 客户端支持的消息格式的版本号
|
||||
/// </summary>
|
||||
public bool ShowVirtual { get; set; }
|
||||
public int V { get; set; }
|
||||
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
public IService Service { get; set; }
|
||||
|
||||
|
||||
public String ServiceName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Service.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
103
Model/MapDataModel.cs
Normal file
103
Model/MapDataModel.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using Newtonsoft.Json;
|
||||
using OnlineUserPool.Unility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OnlineUserPool.Model
|
||||
{
|
||||
public class MapDataModel
|
||||
{
|
||||
public string Type => "LineString";
|
||||
/// <summary>
|
||||
/// 总距离(km)
|
||||
/// </summary>
|
||||
public double TotalDistance { get; set; }
|
||||
|
||||
private List<Item> _List;
|
||||
public List<Item> List
|
||||
{
|
||||
get
|
||||
{
|
||||
return _List;
|
||||
}
|
||||
set
|
||||
{
|
||||
_List = value;
|
||||
if (_List == null) return;
|
||||
this.CalcDistance();
|
||||
this.CalcGrade();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void CalcDistance()
|
||||
{
|
||||
for (int i = 0; i < _List.Count - 1; i++)
|
||||
{
|
||||
var value = CommonHelper.GetDistances(_List[i].Point[1], _List[i].Point[0], _List[i + 1].Point[1], _List[i + 1].Point[0]);
|
||||
//var value = Turf.Distance(pt1, pt2, "kilometers") * 1000;
|
||||
_List[i].Distance = Math.Round(value, 2);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 计算坡度数据
|
||||
/// </summary>
|
||||
private void CalcGrade()
|
||||
{
|
||||
for (int i = 0; i < this._List.Count - 1; i++)
|
||||
{
|
||||
var a = _List[i + 1].Elevation - _List[i].Elevation;
|
||||
if (a == 0)
|
||||
{
|
||||
//grade.Add(0);
|
||||
_List[i].Grade = 0;
|
||||
continue;
|
||||
}
|
||||
//勾股定理
|
||||
var c = _List[i].Distance;//如果车停了下来,c为0
|
||||
if (c == 0 && i > 0)
|
||||
{
|
||||
_List[i].Grade = _List[i - 1].Grade;
|
||||
}
|
||||
else
|
||||
{
|
||||
var b = Math.Sqrt(c * c - a * a);
|
||||
if (b == 0)//如果b等于,这就是垂直的墙壁
|
||||
{
|
||||
_List[i].Grade = _List[i - 1].Grade;
|
||||
}
|
||||
else
|
||||
{
|
||||
_List[i].Grade = Math.Round(a / b * 100, 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MapDataModel()
|
||||
{
|
||||
//_List = new List<Item>();
|
||||
}
|
||||
|
||||
public class Item
|
||||
{
|
||||
/// <summary>
|
||||
/// 坐标(lat,lon)
|
||||
/// </summary>
|
||||
public double[] Point { get; set; }
|
||||
/// <summary>
|
||||
/// 距离(单位米)
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public double Distance { get; set; }
|
||||
/// <summary>
|
||||
/// 海拔m
|
||||
/// </summary>
|
||||
public double Elevation { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public double Grade { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,13 +25,13 @@ namespace OnlineUserPool.Model
|
||||
/// <summary>
|
||||
/// 是否展示在线的人
|
||||
/// </summary>
|
||||
public bool ShowVirtual { get; set; }
|
||||
//public bool ShowVirtual { get; set; }
|
||||
/// <summary>
|
||||
/// 命令类型,0命令,1消息
|
||||
/// </summary>
|
||||
public byte CommandType { get; set; }
|
||||
|
||||
public bool IsVirtual { get; set; }
|
||||
//public bool IsVirtual { get; set; }
|
||||
|
||||
//public double Power { get; set; }
|
||||
//public double Weight { get; set; }
|
||||
@ -43,5 +43,15 @@ namespace OnlineUserPool.Model
|
||||
public int Competitionid { get; set; }
|
||||
|
||||
public bool Saved { get; set; }
|
||||
/// <summary>
|
||||
/// 能处理的消息格式的版本号
|
||||
/// </summary>
|
||||
public int V { get; set; }
|
||||
|
||||
|
||||
public string ToString(int v)
|
||||
{
|
||||
return $"{ RouteId },{ MemberId },{ string.Join(":", Point) },{ Convert.ToInt32(IsCompleted) },{ Speed },{ PreDistance },{ EndDistance },{ WeightKg },{ Competitionid },{ Convert.ToInt32(Saved) }";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,7 +46,11 @@ namespace OnlineUserPool.Model
|
||||
target._Speed = double.Parse(split[2]);
|
||||
target._Distance = double.Parse(split[3]);
|
||||
target._Cadence = double.Parse(split[4]);
|
||||
target._HeartRate = int.Parse(split[5]);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(split[5]) && split[5] != "null")
|
||||
{
|
||||
target._HeartRate = int.Parse(split[5]);
|
||||
}
|
||||
if (split.Length > 6)
|
||||
{
|
||||
target._Lat = double.Parse(split[6]);
|
||||
|
||||
@ -5,7 +5,13 @@
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Services\TcpService.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="GeoJSON.Net" Version="0.1.51" />
|
||||
<PackageReference Include="NetCoreServer" Version="3.0.22" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Prism.Unity" Version="7.2.0.1422" />
|
||||
<PackageReference Include="Prism.Wpf" Version="7.2.0.1422" />
|
||||
@ -14,5 +20,10 @@
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.7.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="TurfCS">
|
||||
<HintPath>..\PowerFun Server\PowerFun Server\lib\TurfCS.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
17
Services/IService.cs
Normal file
17
Services/IService.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using OnlineUserPool.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace OnlineUserPool.Services
|
||||
{
|
||||
public interface IService
|
||||
{
|
||||
public void RunServer(Action<IPEndPoint, MsgModel, IService> action);
|
||||
|
||||
public void Send(byte[] dgram, int bytes, IPEndPoint endPoint);
|
||||
|
||||
public void Close();
|
||||
}
|
||||
}
|
||||
93
Services/TcpService.cs
Normal file
93
Services/TcpService.cs
Normal file
@ -0,0 +1,93 @@
|
||||
using OnlineUserPool.Model;
|
||||
using OnlineUserPool.Unility;
|
||||
using Serilog;
|
||||
using SimpleTcp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OnlineUserPool.Services
|
||||
{
|
||||
public class TcpService : IService
|
||||
{
|
||||
private bool _stop = false;
|
||||
SimpleTcpServer socket;
|
||||
Action<IPEndPoint, MsgModel, IService> _action;
|
||||
|
||||
public void RunServer(Action<IPEndPoint, MsgModel, IService> action)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
|
||||
_action = action;
|
||||
//var ip = IPAddress.Parse("192.168.0.97");
|
||||
var b = IPAddress.Any;
|
||||
socket = new SimpleTcpServer($"{ IPAddress.Any }:11001");
|
||||
socket.Events.ClientConnected += Events_ClientConnected;
|
||||
socket.Events.ClientDisconnected += Events_ClientDisconnected;
|
||||
socket.Events.DataReceived += Events_DataReceived;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
socket.Start();
|
||||
});
|
||||
}
|
||||
|
||||
private void Events_DataReceived(object sender, SimpleTcp.DataReceivedEventArgs e)
|
||||
{
|
||||
var returnData = Encoding.UTF8.GetString(e.Data);
|
||||
Debug.WriteLine(returnData);
|
||||
|
||||
foreach (var item in returnData.Split(new string[] { "}" }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
var msg = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgModel>(item +"}");
|
||||
var ipEndPoint = IPEndPoint.Parse(e.IpPort);
|
||||
_action(ipEndPoint, msg, this);
|
||||
}
|
||||
}
|
||||
|
||||
private void Events_ClientDisconnected(object sender, ClientDisconnectedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Events_ClientConnected(object sender, ClientConnectedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("有新客户端连接" + e.IpPort);
|
||||
}
|
||||
|
||||
public void Send(byte[] dgram, int bytes, IPEndPoint endPoint)
|
||||
{
|
||||
if(dgram == null || !dgram.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var item in socket.GetClients())
|
||||
{
|
||||
//try
|
||||
//{
|
||||
if(socket.IsConnected(item) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
socket.Send(item, dgram);
|
||||
//}
|
||||
//catch(Exception e)
|
||||
//{
|
||||
// Log.Error($"{ item.ToString() }:{ e.Message }\r\n{ e.StackTrace }");
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_stop = true;
|
||||
socket.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Services/TcpService1.cs
Normal file
118
Services/TcpService1.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using NetCoreServer;
|
||||
using OnlineUserPool.Model;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace OnlineUserPool.Services
|
||||
{
|
||||
public class TcpService1 : IService
|
||||
{
|
||||
private PfTcpServer _server;
|
||||
|
||||
public void Close()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RunServer(Action<IPEndPoint, MsgModel, IService> action)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
//_action = action;
|
||||
_server = new PfTcpServer(IPAddress.Any, 11001, (ip, model)=> {
|
||||
action(ip, model, this);
|
||||
});
|
||||
//_server.OptionNoDelay = true;
|
||||
_server.Start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Send(byte[] dgram, int bytes, IPEndPoint endPoint)
|
||||
{
|
||||
if (dgram == null || !dgram.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_server.Multicast(dgram);
|
||||
}
|
||||
|
||||
class PfTcpServer : TcpServer
|
||||
{
|
||||
Action<IPEndPoint, MsgModel> _action;
|
||||
public PfTcpServer(IPAddress address, int port, Action<IPEndPoint, MsgModel> action) :base(address, port)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
protected override TcpSession CreateSession()
|
||||
{
|
||||
//return base.CreateSession()
|
||||
return new PfTcpSession(this, _action);
|
||||
}
|
||||
|
||||
protected override void OnError(SocketError error)
|
||||
{
|
||||
//base.OnError(error);
|
||||
Debug.WriteLine(error);
|
||||
}
|
||||
}
|
||||
|
||||
class PfTcpSession : TcpSession
|
||||
{
|
||||
Action<IPEndPoint, MsgModel> _action;
|
||||
public PfTcpSession(TcpServer server, Action<IPEndPoint, MsgModel> action) : base(server) {
|
||||
_action = action;
|
||||
}
|
||||
|
||||
protected override void OnConnected()
|
||||
{
|
||||
//base.OnConnected();
|
||||
Debug.WriteLine("有新的Tcp连接");
|
||||
}
|
||||
|
||||
protected override void OnDisconnected()
|
||||
{
|
||||
//base.OnDisconnected();
|
||||
Debug.WriteLine("Tcp断开连接");
|
||||
}
|
||||
|
||||
protected override void OnReceived(byte[] buffer, long offset, long size)
|
||||
{
|
||||
//base.OnReceived(buffer, offset, size);
|
||||
var returnData = Encoding.UTF8.GetString(buffer, (int)offset, (int)size);
|
||||
//Debug.WriteLine(returnData);
|
||||
//Log.Information(returnData + "\r\n");
|
||||
try
|
||||
{
|
||||
//var msg = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgModel>(returnData);
|
||||
//var ipEndPoint = IPEndPoint.Parse(this.Socket.RemoteEndPoint.ToString());
|
||||
//_action(ipEndPoint, msg);
|
||||
|
||||
foreach (var item in returnData.Split(new string[] { "}" }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
//if (string.IsNullOrWhiteSpace(item)) continue;
|
||||
var msg = Newtonsoft.Json.JsonConvert.DeserializeObject<MsgModel>(item + "}");
|
||||
var ipEndPoint = IPEndPoint.Parse(this.Socket.RemoteEndPoint.ToString());
|
||||
_action(ipEndPoint, msg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error($"接受到的数据处理时出错:{ returnData }\r\n{ ex.Message }\r\n{ ex.StackTrace }");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnError(SocketError error)
|
||||
{
|
||||
//base.OnError(error);
|
||||
Debug.WriteLine(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Services/UdpService.cs
Normal file
80
Services/UdpService.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using OnlineUserPool.Model;
|
||||
using OnlineUserPool.Unility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OnlineUserPool.Services
|
||||
{
|
||||
public class UdpService : IService
|
||||
{
|
||||
private bool _stop = false;
|
||||
//private static IPEndPoint serverIpEndPoint;
|
||||
private static UdpClient udpServer;
|
||||
|
||||
public UdpService()
|
||||
{
|
||||
//serverIpEndPoint = new IPEndPoint(IPAddress.Parse(ConfigHelp.Ip), ConfigHelp.Port);
|
||||
}
|
||||
|
||||
public void RunServer(Action<IPEndPoint, MsgModel, IService> action)
|
||||
{
|
||||
udpServer = new UdpClient(ConfigHelp.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 (_stop == false)
|
||||
{
|
||||
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
|
||||
action(remoteIpEndPoint, msg, this);
|
||||
|
||||
//if (timer.AutoReset == false)
|
||||
//{
|
||||
// timer.AutoReset = true;
|
||||
//}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Serilog.Log.Error("RunServer:" + e.Message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void Send(byte[] dgram, int bytes, IPEndPoint endPoint)
|
||||
{
|
||||
udpServer.Send(dgram, bytes, endPoint);
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_stop = true;
|
||||
udpServer.Close();
|
||||
}
|
||||
|
||||
void WriteLine(string str)
|
||||
{
|
||||
//Debug.WriteLine(str);
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Unility/CommonHelper.cs
Normal file
27
Unility/CommonHelper.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using TurfCS;
|
||||
|
||||
namespace OnlineUserPool.Unility
|
||||
{
|
||||
public class CommonHelper
|
||||
{
|
||||
public static double GetDistances(double lon, double lat, double lon1, double lat1)
|
||||
{
|
||||
var pt1 = Turf.Point(new double[] { lon, lat });
|
||||
var pt2 = Turf.Point(new double[] { lon1, lat1 });
|
||||
|
||||
var value = Turf.Distance(pt1, pt2, "kilometers") * 1000;
|
||||
return Math.Round(value, 2);
|
||||
}
|
||||
|
||||
public static int GenerateRandomInteger(int min = 0, int max = int.MaxValue)
|
||||
{
|
||||
var randomNumberBuffer = new byte[10];
|
||||
new RNGCryptoServiceProvider().GetBytes(randomNumberBuffer);
|
||||
return new Random(BitConverter.ToInt32(randomNumberBuffer, 0)).Next(min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,20 +7,26 @@ namespace OnlineUserPool.Unility
|
||||
class ConfigHelp
|
||||
{
|
||||
public static string Host { get; set; }
|
||||
public static int Top { get; private set; }
|
||||
public static int Top
|
||||
{
|
||||
get
|
||||
{
|
||||
return Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["Top"]);
|
||||
}
|
||||
}
|
||||
public static bool ShowVirtualUser { get; set; }
|
||||
|
||||
public static string Ip { get; set; }
|
||||
//public static string Ip { get; private set; }
|
||||
|
||||
public static int Port { get; set; }
|
||||
public static int Port { get; private set; }
|
||||
|
||||
|
||||
static ConfigHelp()
|
||||
{
|
||||
Host = System.Configuration.ConfigurationManager.AppSettings["Host"];
|
||||
Top = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["Top"]);
|
||||
//Top = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["Top"]);
|
||||
ShowVirtualUser = bool.Parse(System.Configuration.ConfigurationManager.AppSettings["ShowVirtualUser"]);
|
||||
Ip = System.Configuration.ConfigurationManager.AppSettings["Ip"];
|
||||
//Ip = System.Configuration.ConfigurationManager.AppSettings["Ip"];
|
||||
Port = int.Parse(System.Configuration.ConfigurationManager.AppSettings["Port"]);
|
||||
}
|
||||
}
|
||||
|
||||
38
Unility/TurfHelper.cs
Normal file
38
Unility/TurfHelper.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using GeoJSON.Net.Geometry;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using TurfCS;
|
||||
using System.Linq;
|
||||
|
||||
namespace OnlineUserPool.Unility
|
||||
{
|
||||
public class TurfHelper
|
||||
{
|
||||
private LineString _line;
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="points">坐标(lat,lon)</param>
|
||||
public TurfHelper(IEnumerable<double[]> points)
|
||||
{
|
||||
//var list = new GeoJSON.Net.Geometry.GeographicPosition();
|
||||
var list = points.Select(p => new GeoJSON.Net.Geometry.GeographicPosition(p[0], p[1]));
|
||||
|
||||
_line = new LineString(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="distance">km</param>
|
||||
public GeographicPosition Along(double distance)
|
||||
{
|
||||
var pt1 = Turf.Along(_line, distance);
|
||||
return ((GeographicPosition)((GeoJSON.Net.Geometry.Point)pt1.Geometry).Coordinates);
|
||||
//new LineString()
|
||||
//new GeoJSON.Net.Geometry.Point(new GeoJSON.Net.Geometry.GeographicPosition())
|
||||
//pt1.BoundingBoxes
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,18 +13,19 @@ using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Threading;
|
||||
using System.Diagnostics;
|
||||
using OnlineUserPool.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
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 ConcurrentBag<MsgModel> receiveMes = new ConcurrentBag<MsgModel>();
|
||||
private static object locker = new object();
|
||||
public static System.Timers.Timer timer;
|
||||
private static MapRecordRankingHander mapRecordRankingHander;
|
||||
private static IHandle mapRecordRankingHander;
|
||||
|
||||
private Dispatcher dispatcher;
|
||||
public ObservableCollection<MsgModel> Customers { get; private set; } =
|
||||
@ -40,23 +41,36 @@ namespace OnlineUserPool.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private string _SendDataSize = "";
|
||||
public string SendDataSize
|
||||
{
|
||||
get { return _SendDataSize; }
|
||||
set
|
||||
{
|
||||
SetProperty(ref _SendDataSize, value);
|
||||
}
|
||||
}
|
||||
|
||||
//private IService _udpService;
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
Title = $"{ ConfigHelp.Ip }:{ ConfigHelp.Port }";
|
||||
Title = $"{ IPAddress.Any }:{ ConfigHelp.Port }";
|
||||
|
||||
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($"初始化连接,当前地址:{ IPAddress.Any }:{ConfigHelp.Port}");
|
||||
|
||||
new TcpService1().RunServer(ReceivedData);
|
||||
//var tet = new System.Collections.Concurrent.ConcurrentBag<object>();
|
||||
|
||||
var _udpService = new UdpService();
|
||||
_udpService.RunServer(ReceivedData);
|
||||
|
||||
|
||||
Log.Information("服务启动成功");
|
||||
timer = new System.Timers.Timer(1000);
|
||||
timer.Elapsed += Timer_Elapsed;
|
||||
@ -66,96 +80,67 @@ namespace OnlineUserPool.ViewModels
|
||||
//Console.ReadKey();
|
||||
}
|
||||
|
||||
private void ReceivedData(IPEndPoint remoteIpEndPoint, MsgModel msg, IService service)
|
||||
{
|
||||
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
|
||||
V = msg.V,
|
||||
Service = service
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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 list = CloneJson(receiveMes).ToList();
|
||||
receiveMes.Clear();
|
||||
|
||||
//加入虚拟人物消息
|
||||
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)}");
|
||||
WriteLine($"在线人:{Newtonsoft.Json.JsonConvert.SerializeObject(list)}");
|
||||
//\r\n虚拟人:{Newtonsoft.Json.JsonConvert.SerializeObject(virtualData)}
|
||||
#endif
|
||||
receiveMes.AddRange(virtualData);
|
||||
list.AddRange(virtualData);
|
||||
|
||||
SendMessage(Clients, receiveMes);
|
||||
SendMessage(Clients, list);
|
||||
|
||||
dispatcher.Invoke(() =>
|
||||
{
|
||||
Customers.Clear();
|
||||
foreach (var item in receiveMes)
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (Customers.Any(c => c.MemberId == item.MemberId))
|
||||
{
|
||||
@ -165,20 +150,21 @@ namespace OnlineUserPool.ViewModels
|
||||
}
|
||||
|
||||
//移除下线的客户端
|
||||
for (int i = 0; i < receiveMes.Count; i++)
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (receiveMes[i].exit && !receiveMes[i].IsVirtual)//客户端退出,并且不是虚拟的人物
|
||||
if (list[i].exit && list[i].MemberId >0)//客户端退出,并且不是虚拟的人物
|
||||
{
|
||||
//这个地方有严重的逻辑错误(虚拟的人物不能和真实的人用同一个名字)
|
||||
var info = Clients.FirstOrDefault(n => n.MemberId == receiveMes[i].MemberId);
|
||||
var info = Clients.FirstOrDefault(n => n.MemberId == list[i].MemberId);
|
||||
if (info != null)
|
||||
{
|
||||
Clients.Remove(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
receiveMes.Clear();//删除已经发送的数据
|
||||
//clients.RemoveAll(i => i.Expire);//移除5钟内连接不上的客户端
|
||||
//删除已经发送的数据
|
||||
//receiveMes.Clear();
|
||||
//移除5钟内连接不上的客户端
|
||||
Clients.ToList().ForEach(item =>
|
||||
{
|
||||
if (item.Expire)
|
||||
@ -189,7 +175,7 @@ namespace OnlineUserPool.ViewModels
|
||||
});
|
||||
}
|
||||
//更新虚拟人物信息
|
||||
mapRecordRankingHander.RemoveEndAndAddNewVirtualUser();
|
||||
mapRecordRankingHander.RemoveEndAndAddNewVirtualUser(Customers.Count);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -197,9 +183,17 @@ namespace OnlineUserPool.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendMessage(Collection<HostModel> clients, List<MsgModel> msgModels)
|
||||
private void SendMessage(Collection<HostModel> clients, List<MsgModel> msgModels)
|
||||
{
|
||||
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(msgModels.Select(m=> new {
|
||||
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);
|
||||
}
|
||||
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(list.Select(m=> new {
|
||||
m.RouteId,
|
||||
m.MemberId,
|
||||
m.Point,
|
||||
@ -208,21 +202,42 @@ namespace OnlineUserPool.ViewModels
|
||||
m.Speed,
|
||||
m.PreDistance,
|
||||
m.EndDistance,
|
||||
m.IsVirtual,//后面要把这个字段过滤掉
|
||||
//m.IsVirtual,//后面要把这个字段过滤掉
|
||||
m.WeightKg,
|
||||
m.Competitionid,
|
||||
m.Saved
|
||||
m.Saved,
|
||||
}));
|
||||
var data = Encoding.ASCII.GetBytes(jsonString);
|
||||
foreach (var item in clients)
|
||||
SendDataSize = (data.Length/1000D).ToString() +"KB";
|
||||
|
||||
var strV1 = string.Join("|", list.Select(m => m.ToString(1)));
|
||||
WriteLine(strV1);
|
||||
WriteLine(strV1.Length.ToString());
|
||||
var dataV1 = Encoding.ASCII.GetBytes(strV1);
|
||||
|
||||
SendDataSize += $"\tV1:{ (strV1.Length/1000D) }KB";
|
||||
|
||||
foreach (var item in clients1)
|
||||
{
|
||||
try
|
||||
{
|
||||
udpServer.Send(data, data.Length, item.IPEndPoint);
|
||||
if(item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (item.V == 1)
|
||||
{
|
||||
item.Service.Send(dataV1, dataV1.Length, item.IPEndPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Service.Send(data, data.Length, item.IPEndPoint);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error($"{ item.IPEndPoint.ToString() }:{ e.Message }\r\n{ e.StackTrace }");
|
||||
Debug.WriteLine(e.Message);
|
||||
Log.Error($"{ item.IPEndPoint.ToString() }:{ e.Message }\r\n{ e.StackTrace }");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,7 +245,24 @@ namespace OnlineUserPool.ViewModels
|
||||
|
||||
void WriteLine(string str)
|
||||
{
|
||||
Debug.WriteLine(str);
|
||||
//Debug.WriteLine(str);
|
||||
}
|
||||
|
||||
T CloneJson<T>(T source)
|
||||
{
|
||||
// Don't serialize a null object, simply return the default for that object
|
||||
if (Object.ReferenceEquals(source, null))
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
// initialize inner objects individually
|
||||
// for example in default constructor some list property initialized with some values,
|
||||
// but in 'source' these items are cleaned -
|
||||
// without ObjectCreationHandling.Replace default constructor values will be added to result
|
||||
var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace };
|
||||
|
||||
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(source), deserializeSettings);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
Title="{ Binding Title }" Height="450" Width="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="20"></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
<RowDefinition></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
@ -28,7 +29,13 @@
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>-->
|
||||
<DataGrid ItemsSource="{ Binding Clients }" IsReadOnly="True"></DataGrid>
|
||||
<DataGrid ItemsSource="{ Binding Customers }" Grid.Row="1" IsReadOnly="True"></DataGrid>
|
||||
<TextBlock>
|
||||
<Run Text="在线客户端:"></Run>
|
||||
<Run Text="{ Binding Clients.Count, Mode=OneWay}"></Run>
|
||||
<Run Text="发送单个客户端数据包大小:"></Run>
|
||||
<Run Text="{Binding SendDataSize,Mode=OneWay}"></Run>
|
||||
</TextBlock>
|
||||
<DataGrid ItemsSource="{ Binding Clients }" Grid.Row="1" IsReadOnly="True"></DataGrid>
|
||||
<DataGrid ItemsSource="{ Binding Customers }" Grid.Row="2" IsReadOnly="True"></DataGrid>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user