void ProcessPublish(IChannelHandlerContext context, PublishPacket packet)
        {
            if (!this.ConnectedToService)
            {
                return;
            }

            IMessagingServiceClient sendingClient = this.ResolveSendingClient(packet.TopicName);
            MessageAsyncProcessor <PublishPacket> publishProcessor;

            if (!this.publishProcessors.TryGetValue(sendingClient, out publishProcessor))
            {
                publishProcessor = new MessageAsyncProcessor <PublishPacket>((c, p) => this.PublishToServerAsync(c, sendingClient, p, null));
                publishProcessor.Closed.OnFault(ShutdownOnPublishToServerFaultAction, this);
                this.publishProcessors[sendingClient] = publishProcessor;
            }

            publishProcessor.Post(context, packet);
        }
        public MqttIotHubAdapter(
            Settings settings,
            ISessionStatePersistenceProvider sessionStateManager,
            IDeviceIdentityProvider authProvider,
            IQos2StatePersistenceProvider qos2StateProvider,
            IMessagingFactory messagingFactory,
            IMessageRouter messageRouter)
        {
            Contract.Requires(settings != null);
            Contract.Requires(sessionStateManager != null);
            Contract.Requires(authProvider != null);
            Contract.Requires(messageRouter != null);

            if (qos2StateProvider != null)
            {
                this.maxSupportedQosToClient = QualityOfService.ExactlyOnce;
                this.qos2StateProvider       = qos2StateProvider;
            }
            else
            {
                this.maxSupportedQosToClient = QualityOfService.AtLeastOnce;
            }

            this.settings            = settings;
            this.sessionStateManager = sessionStateManager;
            this.authProvider        = authProvider;
            this.messagingFactory    = messagingFactory;
            this.messageRouter       = messageRouter;

            this.publishProcessor = new MessageAsyncProcessor <PublishPacket>(this.PublishToServerAsync);
            this.publishProcessor.Completion.OnFault(ShutdownOnPublishToServerFaultAction);

            TimeSpan?ackTimeout = this.settings.DeviceReceiveAckCanTimeout ? this.settings.DeviceReceiveAckTimeout : (TimeSpan?)null;

            this.publishPubAckProcessor = new RequestAckPairProcessor <AckPendingMessageState, PublishPacket>(this.AcknowledgePublishAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubAckProcessor.Completion.OnFault(ShutdownOnPubAckFaultAction);
            this.publishPubRecProcessor = new RequestAckPairProcessor <AckPendingMessageState, PublishPacket>(this.AcknowledgePublishReceiveAsync, this.RetransmitNextPublish, ackTimeout);
            this.publishPubRecProcessor.Completion.OnFault(ShutdownOnPubRecFaultAction);
            this.pubRelPubCompProcessor = new RequestAckPairProcessor <CompletionPendingMessageState, PubRelPacket>(this.AcknowledgePublishCompleteAsync, this.RetransmitNextPublishRelease, ackTimeout);
            this.pubRelPubCompProcessor.Completion.OnFault(ShutdownOnPubCompFaultAction);
        }