void SaveMessage(Publish message, string clientId, PendingMessageStatus status) { if (message.QualityOfService == MqttQualityOfService.AtMostOnce) { return; } var session = sessionRepository.Get(s => s.ClientId == clientId); if (session == null) { throw new MqttException(string.Format(Properties.Resources.SessionRepository_ClientSessionNotFound, clientId)); } var savedMessage = new PendingMessage { Status = status, QualityOfService = message.QualityOfService, Duplicated = message.Duplicated, Retain = message.Retain, Topic = message.Topic, PacketId = message.PacketId, Payload = message.Payload }; session.AddPendingMessage(savedMessage); sessionRepository.Update(session); }
public async Task SendPublishAsync(string clientId, Publish message, IMqttChannel <IPacket> channel, PendingMessageStatus status = PendingMessageStatus.PendingToSend) { if (channel == null || !channel.IsConnected) { SaveMessage(message, clientId, PendingMessageStatus.PendingToSend); return; } var qos = configuration.GetSupportedQos(message.QualityOfService); if (qos != MqttQualityOfService.AtMostOnce && status == PendingMessageStatus.PendingToSend) { SaveMessage(message, clientId, PendingMessageStatus.PendingToAcknowledge); } await channel.SendAsync(message) .ConfigureAwait(continueOnCapturedContext: false); if (qos == MqttQualityOfService.AtLeastOnce) { await MonitorAckAsync <PublishAck> (message, clientId, channel) .ConfigureAwait(continueOnCapturedContext: false); } else if (qos == MqttQualityOfService.ExactlyOnce) { await MonitorAckAsync <PublishReceived> (message, clientId, channel).ConfigureAwait(continueOnCapturedContext: false); await channel .ReceiverStream .ObserveOn(NewThreadScheduler.Default) .OfType <PublishComplete> () .FirstOrDefaultAsync(x => x.PacketId == message.PacketId.Value); } }
public async Task SendAckAsync(string clientId, IFlowPacket ack, IMqttChannel <IPacket> channel, PendingMessageStatus status = PendingMessageStatus.PendingToSend) { if ((ack.Type == MqttPacketType.PublishReceived || ack.Type == MqttPacketType.PublishRelease) && status == PendingMessageStatus.PendingToSend) { SavePendingAcknowledgement(ack, clientId); } if (!channel.IsConnected) { return; } await channel.SendAsync(ack) .ConfigureAwait(continueOnCapturedContext: false); if (ack.Type == MqttPacketType.PublishReceived) { await MonitorAckAsync <PublishRelease> (ack, clientId, channel) .ConfigureAwait(continueOnCapturedContext: false); } else if (ack.Type == MqttPacketType.PublishRelease) { await MonitorAckAsync <PublishComplete> (ack, clientId, channel) .ConfigureAwait(continueOnCapturedContext: false); } }