using OnlineUserPool.Api; using OnlineUserPool.Model; using OnlineUserPool.Unility; using Serilog; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; namespace OnlineUserPool.Hander { public class MapRecordRankingHander : IHandle { private static List mapRecordRankings = new List(); private static object locker = new object();//防止服务端响应慢,多次加载 //private int top = ConfigHelp.Top; public MapRecordRankingHander() { Init(); //var timer = new Timer(); //timer } private void Init() { if (ConfigHelp.Top > 0) { var records = WebService.GetMapRouteRandomRecord(START, null); mapRecordRankings.AddRange(WebService.GetRecordFileFromServer(records.Select(n => n.Id).ToList())); UpdateVirtualTime = DateTime.Now; //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())); //} } } private const int START = 15; private const int SMALL = 30; private const int MEDIUM = 50; private const int LARGE = 80; private const int OFFSET = 30; //根据当前时段计算虚拟总人数 private int ComputeTop() { var rand = new Random(); var hour = DateTime.Now.Hour;//当前点数 int offset = 1;//少:1 中:3 多:10 if (hour <= 6) { offset = rand.Next((int)(0.8 * START), (int)(1.2 * START)); } if (hour > 6 && hour <= 18) { offset = rand.Next((int)(0.8 * OFFSET), (int)(1.2 * MEDIUM)); } if (hour >= 18 && hour <= 22) { offset = rand.Next((int)(0.8 * LARGE), (int)(1.2 * LARGE)); } if (hour > 22 && hour <= 24) { offset = rand.Next((int)(0.8 * SMALL), (int)(1.2 * SMALL)); } return offset; } /// /// 获取虚拟人物数据 /// /// public List GetVirtualUserData() { List msgModels = new List(); if(ConfigHelp.ShowVirtualUser == false) { return msgModels; } if (mapRecordRankings != null) { for (int i = 0; i < mapRecordRankings.Count; i++) { try { var item = mapRecordRankings[i]; item.CurrentIndex++; TargetData targetData = item.GetCurrentTargetData(); //List prop = new List() //{ // Math.Round(targetData._Speed, 2).ToString(), // targetData._Power.ToString(), // targetData._Cadence.ToString() //}; var weightKg = 0.0D; if(targetData._Power >= 0) { weightKg = Math.Round(targetData._Power / item.Weight, 2); } if (item.CurrentIndex == 0) { //机器人上线 var loginInfo = new MsgModel() { exit = item.End, IsCompleted = item.End, MemberId = item.UserId,//虚拟的人Id变为负数 Point = new double[] { -1d, -1d }, //Prop = string.Join(',', prop), RouteId = item.RouteId, EndDistance = Math.Round(targetData._Distance, 6), //ShowVirtual = true, CommandType = 1, //IsVirtual = true, Speed = targetData._Speed, WeightKg = weightKg, PreDistance = item.GetPreDistance() }; msgModels.Add(loginInfo); } var info = new MsgModel() { exit = item.End, IsCompleted = item.End, MemberId = item.UserId,//虚拟的人Id变为负数 Point = new double[] { Math.Round(targetData._Lat, 6), Math.Round(targetData._Lon, 6) }, //Prop = string.Join(',', prop), RouteId = item.RouteId, EndDistance = Math.Round(targetData._Distance, 6), //ShowVirtual = true, CommandType = 1, //IsVirtual = true, Speed = targetData._Speed, WeightKg = weightKg, PreDistance = item.GetPreDistance() }; msgModels.Add(info); } catch (Exception e) { Log.Error("加载虚拟人物错误:" + e.Message + "\r\n" + e.StackTrace); } } } return msgModels; } const int offset = 1; const int timeInterval = 15; private DateTime UpdateVirtualTime { get; set; } /// /// 删除已经骑行完的人,添加新的人物进去 /// public void RemoveEndAndAddNewVirtualUser(int customerCount) { lock (locker) { //var offlineCount = mapRecordRankings.Where(c => c.End).Count();//下线人数 var top = ComputeTop();//理论上当前时间段虚拟用户的总数 mapRecordRankings.RemoveAll(n => n.End);//移除骑行结束的人 var routeIds = mapRecordRankings.Select(n => n.RouteId).Distinct().ToList(); var currentVirtualCount = mapRecordRankings.Count(d => d.UserId < 0);//实际虚拟用户数 if (top - currentVirtualCount > 0) { var interval = DateTime.Now - UpdateVirtualTime; if (interval.TotalSeconds > timeInterval) { UpdateVirtualTime = DateTime.Now; var needUpdateCount = offset;//这一秒需要上线的人数 var randomUser = WebService.GetMapRouteRandomRecord(needUpdateCount, routeIds); var addRankings = WebService.GetRecordFileFromServer(randomUser.Select(n => n.Id).ToList()); mapRecordRankings.AddRange(addRankings); } } } } } }