public async Task SubscribeAsync(string topicFilter, MqttQualityOfService qos) { if (disposed) { throw new ObjectDisposedException(GetType().FullName); } try { var packetId = packetIdProvider.GetPacketId(); var subscribe = new Subscribe(packetId, new Subscription(topicFilter, qos)); var ack = default(SubscribeAck); var subscribeTimeout = TimeSpan.FromSeconds(configuration.WaitTimeoutSecs); await SendPacketAsync(subscribe) .ConfigureAwait(continueOnCapturedContext: false); ack = await packetListener .PacketStream .ObserveOn(NewThreadScheduler.Default) .OfType <SubscribeAck> () .FirstOrDefaultAsync(x => x.PacketId == packetId) .Timeout(subscribeTimeout); if (ack == null) { var message = string.Format(Properties.Resources.Client_SubscriptionDisconnected, Id, topicFilter); tracer.Error(message); throw new MqttClientException(message); } if (ack.ReturnCodes.FirstOrDefault() == SubscribeReturnCode.Failure) { var message = string.Format(Properties.Resources.Client_SubscriptionRejected, Id, topicFilter); tracer.Error(message); throw new MqttClientException(message); } } catch (TimeoutException timeEx) { Close(timeEx); var message = string.Format(Properties.Resources.Client_SubscribeTimeout, Id, topicFilter); throw new MqttClientException(message, timeEx); } catch (MqttClientException clientEx) { Close(clientEx); throw; } catch (Exception ex) { Close(ex); var message = string.Format(Properties.Resources.Client_SubscribeError, Id, topicFilter); throw new MqttClientException(message, ex); } }
async Task SendRetainedMessagesAsync(ClientSubscription subscription, IMqttChannel <IPacket> channel) { var retainedMessages = retainedRepository.GetAll() .Where(r => topicEvaluator.Matches(r.Topic, subscription.TopicFilter)); if (retainedMessages != null) { foreach (var retainedMessage in retainedMessages) { ushort?packetId = subscription.MaximumQualityOfService == MqttQualityOfService.AtMostOnce ? null : (ushort?)packetIdProvider.GetPacketId(); var publish = new Publish(retainedMessage.Topic, subscription.MaximumQualityOfService, retain: true, duplicated: false, packetId: packetId) { Payload = retainedMessage.Payload }; await senderFlow.SendPublishAsync(subscription.ClientId, publish, channel) .ConfigureAwait(continueOnCapturedContext: false); } } }
async Task SendRetainedMessagesAsync(ClientSubscription subscription, IMqttChannel <IPacket> channel) { IEnumerable <RetainedMessage> retainedMessages = _retainedRepository .ReadAll() .Where(r => _topicEvaluator.Matches(topicName: r.Id, topicFilter: subscription.TopicFilter)); if (retainedMessages != null) { foreach (RetainedMessage retainedMessage in retainedMessages) { ushort?packetId = subscription.MaximumQualityOfService == MqttQualityOfService.AtMostOnce ? null : (ushort?)_packetIdProvider.GetPacketId(); Publish publish = new Publish(topic: retainedMessage.Id, qualityOfService: subscription.MaximumQualityOfService, retain: true, duplicated: false, packetId: packetId) { Payload = retainedMessage.Payload }; await _senderFlow.SendPublishAsync(subscription.ClientId, publish, channel); } } }
async Task DispatchAsync(Publish publish, ClientSubscription subscription, bool isWill = false) { MqttQualityOfService requestedQos = isWill ? publish.QualityOfService : subscription.MaximumQualityOfService; MqttQualityOfService supportedQos = configuration.GetSupportedQos(requestedQos); bool retain = isWill ? publish.Retain : false; ushort? packetId = supportedQos == MqttQualityOfService.AtMostOnce ? null : (ushort?)_packetIdProvider.GetPacketId(); Publish subscriptionPublish = new Publish(publish.Topic, supportedQos, retain, duplicated: false, packetId: packetId) { Payload = publish.Payload }; IMqttChannel <IPacket> clientChannel = _connectionProvider.GetConnection(subscription.ClientId); await _senderFlow.SendPublishAsync(subscription.ClientId, subscriptionPublish, clientChannel); }
async Task DispatchAsync(Publish publish, ClientSubscription subscription, bool isWill = false) { var requestedQos = isWill ? publish.QualityOfService : subscription.MaximumQualityOfService; var supportedQos = configuration.GetSupportedQos(requestedQos); var retain = isWill ? publish.Retain : false; ushort?packetId = supportedQos == MqttQualityOfService.AtMostOnce ? null : (ushort?)packetIdProvider.GetPacketId(); var subscriptionPublish = new Publish(publish.Topic, supportedQos, retain, duplicated: false, packetId: packetId) { Payload = publish.Payload }; var clientChannel = connectionProvider.GetConnection(subscription.ClientId); await senderFlow.SendPublishAsync(subscription.ClientId, subscriptionPublish, clientChannel) .ConfigureAwait(continueOnCapturedContext: false); }