public async Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { context.AcceptPublish = true; if (context.ApplicationMessage == null) { return; } var payload = context.ApplicationMessage.Payload == null ? null : Encoding.UTF8.GetString(context.ApplicationMessage?.Payload); if (context.ApplicationMessage.Retain) { if (context.ApplicationMessage.Topic.StartsWith("mcu/")) { return; } var msg = _repo.AddMessage(new MqttMessage { Created = DateTime.Now, Message = payload, Topic = context.ApplicationMessage.Topic, ContentType = context.ApplicationMessage.ContentType }); await _repo.SaveChangesAsync(); } // _logger.LogInformation( // $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic}," // + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel}," // + $" Retain-Flag = {context.ApplicationMessage?.Retain}"); }
public async Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context) { //context.AcceptPublish = true; if (context.ApplicationMessage == null) { return; } var payload = context.ApplicationMessage.Payload == null ? null : Encoding.ASCII.GetString(context.ApplicationMessage?.Payload, 0, context.ApplicationMessage.Payload.Count()); if (payload == null) { _logger.LogError( $"Payload is null Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic}," + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel}," + $" Retain-Flag = {context.ApplicationMessage?.Retain}"); return; } var afterPars = Functions.GetPayload(context.ApplicationMessage?.Payload); if (context.ApplicationMessage.Retain) { var msg = _repo.AddMessage(new MqttMessage { Created = DateTime.Now, Message = JsonConvert.SerializeObject(afterPars, Formatting.Indented), Topic = context.ApplicationMessage.Topic, ContentType = context.ApplicationMessage.ContentType }); //var tree = context.ApplicationMessage.Topic.Split('/'); if (await _repo.SaveChangesAsync()) { context.AcceptPublish = true; } } _logger.LogInformation( $"Message: ClientId = {context.ClientId}, Topic = {context.ApplicationMessage?.Topic}," + $" Payload = {payload}, QoS = {context.ApplicationMessage?.QualityOfServiceLevel}," + $" Retain-Flag = {context.ApplicationMessage?.Retain}"); }
private async Task LogMessage(MqttConnectionValidatorContext context, bool newConnection = false, bool showPassword = false) { if (context == null) { return; } if (newConnection) { var connection = new Connection { ClientId = context.ClientId, CleanSession = context.CleanSession, Endpoint = context.Endpoint, Password = context.Password, Username = context.Username }; _repo.AddConnection(connection); await _repo.SaveChangesAsync(); } if (showPassword) { _logger.LogInformation( $"New connection: ClientId = {context.ClientId}, Endpoint = {context.Endpoint}," + $" Username = {context.Username}, Password = {context.Password}," + $" CleanSession = {context.CleanSession}"); } else { _logger.LogInformation( $"New connection: ClientId = {context.ClientId}, Endpoint = {context.Endpoint}," + $" Username = {context.Username}, CleanSession = {context.CleanSession}"); } }
public async Task StartAsync( CancellationToken cancellationToken) { _appLifetime.ApplicationStarted.Register(OnStarted); _appLifetime.ApplicationStopping.Register(OnStopping); _appLifetime.ApplicationStopped.Register(OnStopped); using var scope = _serviceProvider.CreateScope(); var serverBuilder = scope.ServiceProvider.GetRequiredService <IServerBuilder>(); var options = serverBuilder.GetOptionsBuilder(_interceptor, _messageInterceptor); Server = serverBuilder.GetServer(); await Server.StartAsync(options.Build()); Server.StartedHandler = new MqttServerStartedHandlerDelegate(e => { Console.WriteLine("Mqtt Broker start " + e); }); Server.StoppedHandler = new MqttServerStoppedHandlerDelegate(e => { Console.WriteLine("Mqtt Broker stop " + e); }); Server.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(e => { var vehicleId = e.TopicFilter.Topic .Replace("platooning/", "").Replace("/#", ""); _logger.LogInformation("Client subscribed " + e.ClientId + " topic " + e.TopicFilter.Topic + "Vehicle Id " + vehicleId); try { var audit = new Audit { ClientId = e.ClientId, Type = "Sub", Topic = e.TopicFilter.Topic, Payload = JsonConvert.SerializeObject(e.TopicFilter, Formatting.Indented) }; _repo.AddAudit(audit); var sub = _repo.GetSubscribeByTopic(e.ClientId, e.TopicFilter.Topic, e.TopicFilter.QualityOfServiceLevel.ToString()); if (sub != null) { _logger.LogInformation($"There is a subcribe like ClientID {e.ClientId}."); return; } var subClient = new Subscribe { Topic = e.TopicFilter.Topic, Enable = true, ClientId = e.ClientId, QoS = e.TopicFilter.QualityOfServiceLevel.ToString() }; _repo.AddSubscribe(subClient); } catch (Exception exception) { var log = new Log { Exception = exception.StackTrace }; _repo.AddLogAsync(log); _logger.LogError("Error = MqttServerClientSubscribedHandlerDelegate ", exception.StackTrace); } finally { _repo.SaveChangesAsync(cancellationToken); } }); Server.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(e => { try { var clientId = e.ClientId; var topicFilter = e.TopicFilter; _logger.LogInformation($"[{DateTime.Now}] Client '{clientId}' un-subscribed to {topicFilter}."); try { var sub = _repo.GetSubscribeById(e.ClientId).Where(s => s.Topic == topicFilter); var subscribes = sub as List <Subscribe> ?? sub.ToList(); if (subscribes.All(a => a.Topic != topicFilter)) { return; } subscribes .ForEach(a => a.Enable = false); } catch (Exception exception) { var log = new Log { Exception = exception.StackTrace }; _repo.AddLogAsync(log); _logger.LogError("Error = MqttServerClientSubscribedHandlerDelegate ", exception.StackTrace); Console.WriteLine(exception); } } catch (Exception ex) { Console.WriteLine($"[{DateTime.Now}] Client get error " + ex.Message); } finally { _repo.SaveChangesAsync(cancellationToken); } }); Server.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(e => { try { var payload = Functions.GetPayload(e.ApplicationMessage.Payload); var payloadser = JsonConvert.SerializeObject(payload, Formatting.Indented); var tree = e.ApplicationMessage.Topic.Split('/'); var audit = new Audit { ClientId = e.ClientId, Type = "Pub", Topic = e.ApplicationMessage.Topic, Payload = payloadser }; _repo.AddAudit(audit); if (e.ClientId == null) { var log = new Log { Exception = new string("Broker publish message itself " + payloadser + " " + e.ClientId) }; _repo.AddLogAsync(log); //_repo.SaveChangesAsync(cancellationToken); return; } if (!tree.First().Contains("platooning")) { var log = new Log { Exception = new string("Mqtt broker just only response with starting \"platoon\" " + payloadser + " " + e.ClientId) }; _repo.AddLogAsync(log); //_repo.SaveChangesAsync(cancellationToken); return; } if (payload.PlatoonDissolveStatus) { if (_repo.GetPlatoon().Any(a => a.ClientId == e.ClientId && a.IsLead)) { Console.WriteLine( $"[{DateTime.Now}] This is lead Vehicle PlatoonDissolveStatus is true all platoon infor must be deleted" + " Client Id " + e.ClientId + " payload " + payload); var platoonlist = _repo.GetPlatoon().Where(a => a.IsFollower); var platoonlistArray = platoonlist as Platoon[] ?? platoonlist.ToArray(); foreach (var platoon in platoonlistArray) { Server.UnsubscribeAsync(platoon.ClientId, "platooning/broadcast/" + platoon.PlatoonRealId); Server.UnsubscribeAsync(platoon.ClientId, "platooning/" + platoon.ClientId); } _repo.DeletePlatoonRange(platoonlistArray); } else { Console.WriteLine( $"[{DateTime.Now}] This is following Vehicle PlatoonDissolveStatus is true all platoon infor must be deleted" + " Client Id " + e.ClientId + " payload " + payload); var followingVehicle = _repo.GetPlatoon().FirstOrDefault(a => a.IsFollower && a.ClientId == e.ClientId); Server.UnsubscribeAsync(followingVehicle.ClientId, "platooning/" + followingVehicle.ClientId); _repo.DeletePlatoon(followingVehicle); } } if (payload.Maneuver == Maneuver.CreatePlatoon) { if (tree.Length != 4) { var log = new Log { Exception = new string("For creating platoon, topic must 4 length 1. \"platooning\" " + " 2. \"message\" " + " 3. \"leadvehicleID\" " + " 4. \"platoonID\" " + " payload " + payloadser + " " + " client ID " + e.ClientId + " topic " + e.ApplicationMessage.Topic) }; _repo.AddLogAsync(log); //_repo.SaveChangesAsync(cancellationToken); return; } var platoonId = tree[3]; var platoonList = _repo.GetPlatoon().ToList(); var leadVehicleId = tree[2]; var leadVehicle = _repo.GetSubscribeById(leadVehicleId); var pla = platoonList .FirstOrDefault(f => f.Enable && f.PlatoonRealId == platoonId); if (leadVehicle != null && pla == null) { var platoon = new Platoon() { Enable = true, ClientId = e.ClientId, IsLead = true, VechicleId = tree[2], PlatoonRealId = tree[3] }; _repo.AddPlatoon(platoon); Console.WriteLine($"[{DateTime.Now}] Creating new Platoon Client Id " + e.ClientId + " platooning Id" + platoon.PlatoonRealId + " payload " + payloadser); } else { Console.WriteLine($"[{DateTime.Now}] Platoon is already created Client Id " + e.ClientId + " platooning Id" + platoonId + " payload " + payloadser); } } else if (payload.Maneuver == Maneuver.JoinRequest) { if (tree.Length != 3) { var log = new Log { Exception = new string("For joining platoon, topic must 3 length 1. \"platooning\" " + " 2. \"message\" " + " 3. \"followingVehicleId\" " + " 4. \"#\" " + " payload " + payloadser + " " + " client ID " + e.ClientId + " topic " + e.ApplicationMessage.Topic) }; _repo.AddLogAsync(log); //_repo.SaveChangesAsync(); return; } var isFollowing = _repo.GetPlatoon() .FirstOrDefault(f => f.IsFollower && f.VechicleId == tree[2] && f.Enable); if (isFollowing != null) { return; } var platoonLead = _repo.GetPlatoon().FirstOrDefault(f => f.IsLead && f.Enable); if (platoonLead != null) { var platoon = new Platoon() { Enable = false, ClientId = e.ClientId, IsLead = false, IsFollower = true, VechicleId = tree[2], PlatoonRealId = platoonLead.PlatoonRealId }; _repo.AddPlatoon(platoon); Console.WriteLine($"[{DateTime.Now}] Join Platoon Client Id " + e.ClientId + " platooning Id" + platoon.PlatoonRealId + " payload " + payloadser); var message = new BitArray(_dataLenght); message.Set(0, false); message.Set(1, false); message.Set(2, true); Server.PublishAsync("platooning/" + platoonLead.ClientId + "/" + tree[2], Encoding.ASCII.GetString(Functions.BitArrayToByteArray(message))); } } else if (payload.Maneuver == Maneuver.JoinAccepted) { Console.WriteLine($"[{DateTime.Now}] Join accepted Client Id " + e.ClientId + " payload " + payloadser); var followvehicleId = tree[1]; var leadVehicle = tree[2]; var plattonId = tree[3]; var allplatoon = _repo.GetPlatoon(); if (allplatoon != null) { var enumerable = allplatoon as Platoon[] ?? allplatoon.ToArray(); var platoonfollow = enumerable.FirstOrDefault(f => f.IsFollower && f.ClientId == followvehicleId); if (platoonfollow != null) { platoonfollow.Enable = true; platoonfollow.PlatoonRealId = plattonId; _repo.UpdatePlatoon(platoonfollow); } else { var platoonlead = enumerable .FirstOrDefault(f => f.IsLead && f.Enable && f.ClientId == leadVehicle); if (platoonlead != null) { var platoon = new Platoon() { Enable = true, ClientId = e.ClientId, IsLead = false, IsFollower = true, VechicleId = followvehicleId, PlatoonRealId = platoonlead.PlatoonRealId }; _repo.AddPlatoon(platoon); } } } } else if (payload.Maneuver == Maneuver.JoinRejected) { Console.WriteLine($"[{DateTime.Now}] Join rejected Client Id " + e.ClientId + " payload " + payloadser); var platoonfollow = _repo.GetPlatoon() .FirstOrDefault(f => f.IsFollower && f.ClientId == tree[1]); if (platoonfollow != null) { _repo.DeletePlatoon(platoonfollow); } } else { var log = new Log { Exception = new string("Unknown Maneuver " + payloadser + " " + e.ClientId) }; _repo.AddLogAsync(log); } } catch (Exception exception) { Console.WriteLine(exception); var log = new Log { Exception = exception.StackTrace }; _repo.AddLogAsync(log); } finally { _repo.SaveChangesAsync(cancellationToken); } OnDataReceived(e.ApplicationMessage.Payload); }); }
private async void InsertValues( object state) { if (_running) { _logger.LogInformation(4444, $"Job is already running"); return; } _running = true; var lastTimestamp = _repository.LastTimestamp(); var currentTimestamp = lastTimestamp.AddMinutes(1); while (currentTimestamp < DateTime.Now.CutSeconds()) { _ = _repository.AddTimestamp(currentTimestamp.CutSeconds()); currentTimestamp = currentTimestamp.AddMinutes(1); } _ = await _repository.SaveChangesAsync(); var targets = new List <MeasureValue>(); var delete = new List <MqttMessage>(); // Filter relevant messages var messages = await _repository .GetMessagesAsQueryable() .Where(msg => !msg.Topic.EndsWith("neo7m")) .OrderBy(msg => msg.Created) .ToListAsync(); foreach (var message in messages) { if (!double.TryParse(message.Message, out var v)) { delete.Add(message); continue; } var fields = message.Topic.Split('/'); if (fields.Length != 4) { delete.Add(message); continue; } var tmpTimestamp = message.Created.CutSeconds(); var timestamp = _repository.GetTimestamp(tmpTimestamp); if (timestamp == null) { _logger.LogInformation($"Timestamp {tmpTimestamp.ToString()} not exist"); continue; } var room = _repository.GetRoom(fields[1]); var measureType = _repository.GetMeasureType(fields[2]); var sensorType = _repository.GetSensorType(fields[3]); if (room == null && measureType == null && sensorType == null) { _logger.LogError(6666, $"Error with types"); continue; } var value = new MeasureValue { MeasureTimeTimestamp = timestamp.Timestamp, SensorTypeName = sensorType.Name, RoomName = room?.Name, MeasureTypeName = measureType?.Name, Value = v }; if (targets.FirstOrDefault( msg => msg.RoomName == value.RoomName && msg.SensorTypeName == value.SensorTypeName && msg.MeasureTypeName == value.MeasureTypeName && msg.MeasureTimeTimestamp == value.MeasureTimeTimestamp) != null) { _logger.LogError(4444, $"Value are duplicate in MqttMessages"); delete.Add(message); continue; } targets.Add(value); delete.Add(message); } foreach (var target in targets) { if (!_repository.MeasureExists( target.RoomName, target.MeasureTypeName, target.SensorTypeName, target.MeasureTimeTimestamp)) { _repository.AddMeasureValue(target); } } foreach (var dMessage in delete) { _repository.DeleteMessage(dMessage); } _ = await _repository.SaveChangesAsync(); _running = false; }