public Task Execute(IJobExecutionContext context) { return(Task.Run(async() => { //如果中断在mqtt服务器列表中, 则取得最后一次收到消息的时间戳, using (var scope = _scopeFactor.CreateScope()) using (var _dbContext = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>()) { var clientstatus = await _serverEx.GetClientStatusAsync(); clientstatus.ToList().ForEach(cs => { if (_device.Exists(cs.ClientId)) { var dev = _device.Get <Device>(cs.ClientId); var d = _dbContext.Device.FirstOrDefault(d => d.Id == dev.Value.Id); if (d != null) { d.LastActive = cs.LastPacketReceivedTimestamp; } } }); //如果超时小于1 就设置为默认300秒 var tfx = from d in _dbContext.Device where d.Timeout < 1 select d; tfx.ToList().ForEach(d => d.Timeout = 300); //当前时间减去最后活跃时间如果小于超时时间, 则为在线, 否则就是离线 _dbContext.Device.ToList().ForEach(d => { d.Online = DateTime.Now.Subtract(d.LastActive).TotalSeconds < d.Timeout; }); await _dbContext.SaveChangesAsync(); } })); }
public MQTTServerHandler(ILogger <MQTTServerHandler> logger, IServiceScopeFactory scopeFactor, IMqttServerEx serverEx, DiagnosticsService diagnosticsService, RuntimeStatusHandler systemStatusService, IOptions <AppSettings> options ) { _mcsetting = options.Value.MqttClient; _logger = logger; scope = scopeFactor.CreateScope(); _dbContext = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>(); _serverEx = serverEx; InboundCounter = diagnosticsService.CreateOperationsPerSecondCounter("mqtt.inbound_rate"); OutboundCounter = diagnosticsService.CreateOperationsPerSecondCounter("mqtt.outbound_rate"); systemStatusService.Set("mqtt.subscribers_count", () => Subscribers.Count); systemStatusService.Set("mqtt.incoming_messages_count", () => IncomingMessages.Count); systemStatusService.Set("mqtt.inbound_rate", () => InboundCounter.Count); systemStatusService.Set("mqtt.outbound_rate", () => OutboundCounter.Count); systemStatusService.Set("mqtt.connected_clients_count", () => serverEx.GetClientStatusAsync().GetAwaiter().GetResult().Count); }
public Task Execute(IJobExecutionContext context) { return(Task.Run(async() => { //如果中断在mqtt服务器列表中, 则取得最后一次收到消息的时间戳, using (var scope = _scopeFactor.CreateScope()) using (var _dbContext = scope.ServiceProvider.GetRequiredService <ApplicationDbContext>()) { var clientstatus = await _serverEx.GetClientStatusAsync(); clientstatus.ToList().ForEach(cs => { try { var _device = cs.Session.Items?.FirstOrDefault(k => (string)k.Key == nameof(Device)).Value as Device; var d = _dbContext.Device.FirstOrDefault(d => d.Id == _device.Id); if (d != null) { d.LastActive = cs.LastPacketReceivedTimestamp.ToLocalTime(); d.Online = DateTime.Now.Subtract(d.LastActive).TotalSeconds < d.Timeout; _logger.LogInformation($"设备{cs.ClientId}-{d.Name}({d.Id},{cs.Endpoint}) 最后活动时间{d.LastActive} 在线{d.Online} 发送消息:{cs.SentApplicationMessagesCount}({cs.BytesSent}kb) 收到{cs.ReceivedApplicationMessagesCount}({cs.BytesReceived / 1024}KB ) "); if (!d.Online && DateTime.Now.Subtract(d.LastActive).TotalSeconds > d.Timeout * 5) { Task.Run(cs.DisconnectAsync); } } } catch (Exception ex) { _logger.LogInformation($"检查设备{cs.ClientId}-{cs.Endpoint}) 时遇到异常{ex.Message}{ex.InnerException?.Message} 发送消息:{cs.SentApplicationMessagesCount}({cs.BytesSent}kb) 收到{cs.ReceivedApplicationMessagesCount}({cs.BytesReceived / 1024}KB ) "); } }); var tfx = from d in _dbContext.Device where d.Timeout < 1 select d; tfx.ToList().ForEach(d => d.Timeout = 300); //当前时间减去最后活跃时间如果小于超时时间, 则为在线, 否则就是离线 _dbContext.Device.ToList().ForEach(d => { d.Online = DateTime.Now.Subtract(d.LastActive).TotalSeconds < d.Timeout; }); var saveresult = await _dbContext.SaveChangesAsync(); _logger.LogInformation($"设备检查程序已经处理{saveresult}调数据"); } })); }
public Task <IList <IMqttClientStatus> > GetClientsAsync() { return(_serverEx.GetClientStatusAsync()); }
public async Task <ActionResult <IList <IMqttClientStatus> > > GetClientStatus(Guid deviceId) { return(Ok(new ApiResult <IList <IMqttClientStatus> >(ApiCode.Success, "OK", await _serverEx.GetClientStatusAsync()))); }
internal void Server_ApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) { if (string.IsNullOrEmpty(e.ClientId)) { _logger.LogInformation($"Message: Topic=[{e.ApplicationMessage.Topic }]"); } else { _logger.LogInformation($"Server received {e.ClientId}'s message: Topic=[{e.ApplicationMessage.Topic }],Retain=[{e.ApplicationMessage.Retain}],QualityOfServiceLevel=[{e.ApplicationMessage.QualityOfServiceLevel}]"); if (!lstTopics.ContainsKey(e.ApplicationMessage.Topic)) { lstTopics.Add(e.ApplicationMessage.Topic, 1); Task.Run(() => _serverEx.PublishAsync("$SYS/broker/subscriptions/count", lstTopics.Count.ToString())); } else { lstTopics[e.ApplicationMessage.Topic]++; } if (e.ApplicationMessage.Payload != null) { received += e.ApplicationMessage.Payload.Length; } string topic = e.ApplicationMessage.Topic; var tpary = topic.Split('/', StringSplitOptions.RemoveEmptyEntries); if (tpary.Length >= 3 && tpary[0] == "devices" && _device.Exists(e.ClientId)) { Device device = JudgeOrCreateNewDevice(tpary, _device.Get <Device>(e.ClientId).Value); if (device != null) { Dictionary <string, object> keyValues = new Dictionary <string, object>(); if (tpary.Length >= 4) { string keyname = tpary.Length >= 5 ? tpary[4] : tpary[3]; if (tpary[3].ToLower() == "xml") { try { var xml = new System.Xml.XmlDocument(); xml.LoadXml(e.ApplicationMessage.ConvertPayloadToString()); keyValues.Add(keyname, xml); } catch (Exception ex) { _logger.LogWarning(ex, $"xml data error {topic},{ex.Message}"); } } else if (tpary[3].ToLower() == "binary") { keyValues.Add(keyname, e.ApplicationMessage.Payload); } } else { try { keyValues = e.ApplicationMessage.ConvertPayloadToDictionary(); } catch (Exception ex) { _logger.LogWarning(ex, $"ConvertPayloadToDictionary Error {topic},{ex.Message}"); } } var devx = _device.Get <Device>(e.ClientId); _device.TrySet(e.ClientId, devx.Value, TimeSpan.FromDays(365)); if (tpary[2] == "telemetry") { _queue.PublishTelemetryData(new RawMsg() { DeviceId = device.Id, MsgBody = keyValues, DataSide = DataSide.ClientSide, DataCatalog = DataCatalog.TelemetryData }); } else if (tpary[2] == "attributes") { if (tpary.Length > 3 && tpary[3] == "request") { Task.Run(async() => { await RequestAttributes(tpary, e.ApplicationMessage.ConvertPayloadToDictionary(), device); }); } else { _queue.PublishAttributeData(new RawMsg() { DeviceId = device.Id, MsgBody = keyValues, DataSide = DataSide.ClientSide, DataCatalog = DataCatalog.AttributeData }); } } } } else { Task.Run(async() => { var ss = await _serverEx.GetClientStatusAsync(); ss.FirstOrDefault(t => t.ClientId == e.ClientId)?.DisconnectAsync(); }); } } }