protected override void HeartBeatProcessor() { // TODO: Refactor to a method or may be class PlatformMessage platformMessage = new PlatformMessage() { Command = new Core.Platform.Commands.Command() { CommandCode = Core.Platform.Commands.CommandCode.HeartBeat, CommandType = Core.Platform.Commands.CommandTransfer.Random, }, NextJump = null }; HeartBeatModel heartBeatModel = new HeartBeatModel() { ChannelId = bootstrap.GetVariableSet("Termination"), SentTime = DateTime.Now, Id = hostedMachine.Id, Model = "Hydralisk", External = hostedMachine }; platformMessage.Routes.Add(new MessageRoute( new Pricipal() { Id = hostedMachine.Id, IpAddress = hostedMachine.PrivateIpAddress } )); platformMessage.MessageData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(heartBeatModel)); messageOut.SendQueueMessage(platformMessage).Wait(); }
public static CachedRecordingModel ToCachedRecordModel(this HeartBeatModel source) { var cachedCachedRecordingModel = new CachedRecordingModel { CarName = source.robot_id, }; return(cachedCachedRecordingModel); }
public async Task ProcessAsync(PlatformMessage platformMessage) { string hbdInfo = Encoding.UTF8.GetString(platformMessage.MessageData); HeartBeatModel heartBeatModel = JsonConvert.DeserializeObject <HeartBeatModel>(hbdInfo); await channelStatus.StoreAsync("instance-" + heartBeatModel.Id, heartBeatModel, new TimeSpan(0, 0, 10)); await channelStatus.StoreAsync("channel-" + heartBeatModel.ChannelId, new ChannelModel() { Congestion = (DateTime.Now - heartBeatModel.SentTime).TotalMilliseconds, Id = heartBeatModel.ChannelId }, new TimeSpan(0, 0, 10)); }
/// <summary> /// 相机心跳数据发送至页面 /// </summary> /// <param name="model"></param> /// <returns></returns> private static bool SendHeartBeatToClient(HeartBeatModel model) { RequestFujicaMvcApi request = new RequestFujicaMvcApi(); //请求方法 string servername = "Capture/HeartBeatSend"; //请求参数 Dictionary <string, object> dicParam = new Dictionary <string, object>(); dicParam["TimeStamp"] = model.TimeStamp; //时间戳 dicParam["ParkingCode"] = model.ParkingCode; //停车场编码 dicParam["DeviceIdentify"] = model.DeviceIdentify; //相机设备地址 return(request.RequestInterfaceMvc(servername, dicParam)); }
public void Add(HeartBeatModel model) { if (model == null) { return; } if (funcQueue.Count > MedivhConfig.MaxHeartBeatCount) { throw new TargetParameterCountException("HeartBeat max count is " + MedivhConfig.MaxHeartBeatCount); } funcQueue.Enqueue(model); }
public void Add(HeartBeatModel model) { if (model == null || string.IsNullOrWhiteSpace(model.Mark) || model.Action == null) { return; } try { HeartBeatJob.Instance().Add(model); } catch (Exception ex) { LogHelper.Error(ex); } }
public async Task <IActionResult> Post([FromBody] HeartBeatModel heartBeatModel) { if (ModelState.IsValid) { var heartBeat = new HeartBeat { Device = heartBeatModel.Device, HeartBeatTime = DateTime.UtcNow, IPAddress = HttpContext.Connection.RemoteIpAddress.ToString() }; _database.Entry(heartBeat).State = EntityState.Added; await _database.SaveChangesAsync(); return(Ok()); } return(BadRequest(ModelState)); }
public IHttpActionResult HeartBeatSend(HeartBeatModel model) { ResponseBaseCommon response = new ResponseBaseCommon() { IsSuccess = false, MessageCode = (int)ApiBaseErrorCode.API_FAIL, MessageContent = "请求失败" }; List <string> laneIds = new List <string>() { }; if (model.ParkingCode != null && model.DeviceIdentify != null) { laneIds.Add(model.ParkingCode); } Clients.Groups(laneIds).heartBeatMessage(model); //broadcastMessage response.IsSuccess = true; response.MessageCode = (int)ApiBaseErrorCode.API_SUCCESS; response.MessageContent = "请求成功"; return(Ok(response)); }
private static void printReceiveMsg(object reciveClient) { /* */ /* 用来打印接收的消息*/ /* */ TcpClient client = reciveClient as TcpClient; if (client == null) { Console.WriteLine("client error"); return; } try { NetworkStream stream = client.GetStream(); while (true) { byte[] result = new byte[1024]; int num = 0; try { num = stream.Read(result, 0, result.Length); //将数据读到result中,并返回字符长度 } catch (IOException ex) { Logger.Instance.Log(LogLevel.Warning, $"IO exception detected, client {client.Client.RemoteEndPoint.ToString()} might be disconnected"); } if (num != 0) { string str = Encoding.UTF8.GetString(result, 0, num);//把字节数组中流存储的数据以字符串方式赋值给str Logger.Instance.Log(LogLevel.Information, $"From: " + client.Client.RemoteEndPoint.ToString() + " : " + str); try { var rows = str.Split(new string[] { "}{" }, StringSplitOptions.None); foreach (var aRow in rows) { var validatedStr = aRow.FormatValidJson(); HeartBeatModel heartBeat = JsonConvert.DeserializeObject <HeartBeatModel>(validatedStr); if (heartBeat.robot_id == 0) { continue; } if (heartBeat != null) { //zhu che if (heartBeat.robot_id == Const.MAIN_CAR_ID) { //update current postion RedisHelper.Instance.SetCache <HeartBeatModel>("main", heartBeat).Wait(); //carInCache.CurrentPosition = new Coordinate(_heartBeat.longitude, _heartBeat.latitude); //add to the coordinate list //carInCache.CachedCoordinates.Add(new Coordinate(_heartBeat.longitude, _heartBeat.latitude)); //trigger other route if possible var _cars = RedisHelper.Instance.GetCurrentCarsInCache().Result; foreach (var cachedModel in _cars) { Logger.Instance.Log(LogLevel.Information, $"checking trigger point for robot {cachedModel.CarName}"); if (cachedModel.RouteStatus == 1) { Logger.Instance.Log(LogLevel.Information, $"calculating robot {cachedModel.CarName} trigger point: {cachedModel.TriggerPoint.Longitude}, {cachedModel.TriggerPoint.Latitude}. Main car long:{heartBeat.longitude}, lat: {heartBeat.latitude}"); if (cachedModel.TriggerPoint.IsInRange(heartBeat.longitude, heartBeat.latitude)) { //trigger the route now //go to auto pilot mode and send the coordinates to client Logger.Instance.Log(LogLevel.Information, $"robot {cachedModel.CarName} is getting triggered by main car"); var outbound = new OutboundModel(); outbound.CarName = cachedModel.CarName; outbound.Data = new List <object>(); outbound.Ip = cachedModel.Ip; //切换⾄数据传输模式 outbound.Data.Add(new msg_control_cmd() { cmd = 1, cmd_slave = 3, route_id = 0 }); //循迹驾驶 outbound.Data.Add(new msg_control_cmd() { cmd = 1, cmd_slave = 1, route_id = 0, check = 8, speed = cachedModel.Speed }); RedisHelper.Instance.SetCache("command", outbound).Wait(); //update database with the //update cache status to action cachedModel.RouteStatus = 2; cachedModel.IsDirty = true; Logger.Instance.Log(LogLevel.Information, $"dirty car found, db sync {cachedModel.CarId}"); _carDbService.SyncRoute(cachedModel).Wait(); cachedModel.IsDirty = false; } } } } //fu che else { //Check if the car is in cache //get cache car list var carInCache = RedisHelper.Instance.TryGetFromCarList($"car_{heartBeat.robot_id}").Result; var updateCache = false; if (carInCache == null) { //new robot registers carInCache = heartBeat.ToCachedRecordModel(); //ADD TO DB IF NOT EXIST _carDbService.AddCarIfNotExist(carInCache); //READ FROM DB var carInDb = _carDbService.GetCarByName(heartBeat.robot_id); carInCache.CarId = carInDb.Id; carInCache.Ip = client.Client.RemoteEndPoint.ToString(); //Console.WriteLine($"attempt loading car from db: {carInDb.CarName}, {client.Client.RemoteEndPoint.ToString()}"); Logger.Instance.Log(LogLevel.Information, $"attempt loading car from db: {carInCache.CarName}, {client.Client.RemoteEndPoint.ToString()}"); updateCache = true; //add to the cache RedisHelper.Instance.AddCachedNameIndex(carInCache.CarName); Logger.Instance.Log(LogLevel.Information, "new robot added successfully " + client.Client.RemoteEndPoint.ToString()); } else { ///Ip will change randomly upon reconnect Logger.Instance.Log(LogLevel.Information, $"loaded robot '{heartBeat.robot_id}' successfully from cache:" + client.Client.RemoteEndPoint.ToString()); if (carInCache.Ip != client.Client.RemoteEndPoint.ToString()) { carInCache.Ip = client.Client.RemoteEndPoint.ToString(); updateCache = true; } } if (updateCache) { var carInDb = _carDbService.GetCarByName(heartBeat.robot_id); var latestRouteIfAny = _carDbService.LatestRoute(carInDb.Id); //ready to be triggered by main car if (latestRouteIfAny != null && latestRouteIfAny.RouteStatus == 1) { carInCache.ImpotedCoordinates = latestRouteIfAny.ImportedCarTrack; carInCache.RouteId = latestRouteIfAny.Id; carInCache.RouteStatus = latestRouteIfAny.RouteStatus; } RedisHelper.Instance.SetCache($"car_{carInCache.CarName}", carInCache).Wait(); } //fu che //verify the car status in cache consitent with client if (heartBeat.robot_status == carInCache.RobotStatus) { Console.WriteLine($"synced Robot {client.Client.RemoteEndPoint.ToString()} status {heartBeat.robot_status}"); //update current position in cache carInCache.CurrentPosition = new Coordinate(heartBeat.longitude, heartBeat.latitude); carInCache.Speed = heartBeat.speed; carInCache.Battery = heartBeat.battery; //recording //// 1 == REMOTE CONTROL MODE if (heartBeat.robot_status == Const.ROBOT_STATUS_REMOTE) { Console.WriteLine($"remote control request: update coordinate {heartBeat.longitude}, {heartBeat.latitude}"); //add the coordinate to the cache carInCache.CachedCoordinates.Add(new Coordinate(heartBeat.longitude, heartBeat.latitude)); } //2 == AUTO PILOT MODE else if (heartBeat.robot_status == Const.ROBOT_STATUS_AUTO_PILOT) { //add the coordinates to the cache carInCache.CachedCoordinates.Add(new Coordinate(heartBeat.longitude, heartBeat.latitude)); //is the current position within the endpoint? if (carInCache.EndPoint.IsInRange(heartBeat.longitude, heartBeat.latitude)) { //send to client to stop auto pilot mode var outbound = new OutboundModel(carInCache.Ip, carInCache.CarName); RedisHelper.Instance.SetCache("command", outbound).Wait(); //update database with the cached coordinates _carDbService.UpdateRouteWithCoordinates(null, carInCache.IsReturn); //update cache status to idle carInCache.RouteStatus++; //end of the process //if (carInCache.RouteStatus == 4) //{ // RedisHelper.Instance.ClearKey("car_{ip}"); //} } } //update cache RedisHelper.Instance.SetCache($"car_{carInCache.CarName}", carInCache).Wait(); } } } } } catch (Exception e) { Logger.Instance.Log(LogLevel.Error, e.Message); } //TODO REMOVE //服务器收到消息后并会给客户端一个消息。 string msg = str; result = Encoding.UTF8.GetBytes(msg); //stream = client.GetStream(); stream.Write(result, 0, result.Length); stream.Flush(); } else { //这里需要注意 当num=0时表明客户端已经断开连接,需要结束循环,不然会死循环一直卡住 clients.Remove(client); Console.WriteLine("client closed"); stream.Dispose(); break; } } stream.Dispose(); } catch (Exception e) { clients.Remove(client); Console.WriteLine("error:" + e.ToString()); Logger.Instance.Log(LogLevel.Error, e.Message); } }
public static ResponseCommon DataHandle(ILogger m_ilogger, ISerializer m_serializer) { ResponseCommon response = new ResponseCommon() { IsSuccess = false, MsgType = MsgType.HeartBeat }; IDatabase db; db = RedisHelper.GetDatabase(4); string redisContent = db.ListLeftPop(mq_ListKey); if (string.IsNullOrEmpty(redisContent)) { response.MessageContent = "redis数据库读取值为空"; return(response); } response.RedisContent = redisContent; m_ilogger.LogInfo(LoggerLogicEnum.Tools, "", "", "", "Fujica.com.cn.MonitorServiceClient.HeartBeatDataManager", "相机心跳数据接收成功。原始数据:" + redisContent); HeartBeatModel heartModel = m_serializer.Deserialize <HeartBeatModel>(redisContent); if (heartModel == null) { response.MessageContent = "redis数据库读取值转换成实体失败:"; return(response); } if (string.IsNullOrEmpty(heartModel.TimeStamp) || string.IsNullOrEmpty(heartModel.DeviceIdentify) || string.IsNullOrEmpty(heartModel.ParkingCode) ) { response.MessageContent = "redis数据转换成实体后必要参数缺失"; return(response); } string hashKey = "HeartBeatList:" + heartModel.ParkingCode; db = RedisHelper.GetDatabase(0); //因相机和服务器时间同步问题,暂时不使用相机时间进行数据更新 //db.HashSet(hashKey, heartModel.DeviceIdentify, Regex.Replace(heartModel.TimeStamp, @"(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})", "$1-$2-$3 $4:$5:$6")); db.HashSet(hashKey, heartModel.DeviceIdentify, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); db.KeyExpire(hashKey, DateTime.Now.AddDays(1));//一天后自动过期 bool flag = db.HashExists(hashKey, heartModel.DeviceIdentify); if (flag) { response.IsSuccess = true; response.MessageContent = heartModel.DeviceIdentify + "相机心跳数据添加redis成功"; m_ilogger.LogInfo(LoggerLogicEnum.Tools, "", "", "", "Fujica.com.cn.MonitorServiceClient.HeartBeatDataManager", heartModel.DeviceIdentify + "相机心跳数据添加redis成功"); #region 相机心跳数据发送至页面 HeartBeatModel model = new HeartBeatModel() { TimeStamp = heartModel.TimeStamp, ParkingCode = heartModel.ParkingCode, DeviceIdentify = heartModel.DeviceIdentify }; SendHeartBeatToClient(model); #endregion return(response); } else { response.MessageContent = heartModel.DeviceIdentify + "相机心跳数据添加redis失败"; m_ilogger.LogInfo(LoggerLogicEnum.Tools, "", heartModel.ParkingCode, "", "Fujica.com.cn.MonitorServiceClient.HeartBeatDataManager", heartModel.DeviceIdentify + "相机心跳数据添加redis失败"); return(response); } }