Exemple #1
0
        async void CloseServiceConnection(IChannelHandlerContext context, Exception cause, PublishPacket will)
        {
            if (!this.ConnectedToService)
            {
                // closure happened before IoT Hub connection was established or it was initiated due to disconnect
                return;
            }

            try
            {
                foreach (var publishProcessor in this.publishProcessors)
                {
                    publishProcessor.Value.Complete();
                }
                this.publishPubAckProcessor.Complete();
                this.publishPubRecProcessor.Complete();
                this.pubRelPubCompProcessor.Complete();
                await Task.WhenAll(
                    this.CompletePublishAsync(context, will),
                    this.publishPubAckProcessor.Completion,
                    this.publishPubRecProcessor.Completion,
                    this.pubRelPubCompProcessor.Completion);

                IMessagingBridge bridge = this.messagingBridge;
                this.messagingBridge = null;
                await bridge.DisposeAsync(cause);
            }
            catch (Exception ex)
            {
                CommonEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString(), this.ChannelId);
            }
        }
        async void ShutdownOnReceiveError(Exception cause)
        {
            this.publishPubAckProcessor.Close();
            foreach (var publishProcessor in this.publishProcessors)
            {
                publishProcessor.Value.Close();
            }
            this.publishPubRecProcessor.Close();
            this.pubRelPubCompProcessor.Close();

            IMessagingBridge bridge = this.messagingBridge;

            if (bridge != null)
            {
                this.messagingBridge = null;
                try
                {
                    await bridge.DisposeAsync(cause);
                }
                catch (Exception ex)
                {
                    CommonEventSource.Log.Info("Failed to close IoT Hub Client cleanly: " + ex, this.ChannelId, this.Id);
                }
            }
            ShutdownOnError(this.capturedContext, ReceiveProcessingScope, cause);
        }
Exemple #3
0
        async Task CloseServiceConnection(IChannelHandlerContext context, Exception cause, PublishPacket will)
        {
            if (!this.ConnectedToService)
            {
                // closure happened before IoT Hub connection was established or it was initiated due to disconnect
                if (cause != null)
                {
                    string causeScope = (string)cause.Data[OperationScopeExceptionDataKey] ?? "unknown";
                    CommonEventSource.Log.Error($"Connection closed while not fully connected. Scope: {causeScope}", cause, this.ChannelId, this.Id);
                }

                return;
            }

            try
            {
                this.publishPubAckProcessor.Close();
                this.publishPubRecProcessor.Close();
                this.pubRelPubCompProcessor.Close();

                await Task.WhenAll(
                    this.CompletePublishAsync(context, will),
                    this.publishPubAckProcessor.Closed,
                    this.publishPubRecProcessor.Closed,
                    this.pubRelPubCompProcessor.Closed);
            }
            catch (Exception ex)
            {
                CommonEventSource.Log.Info("Failed to complete the processors: " + ex.ToString(), this.ChannelId, this.Id);
            }

            try
            {
                IMessagingBridge bridge = this.messagingBridge;
                if (this.messagingBridge != null)
                {
                    this.messagingBridge = null;
                    await bridge.DisposeAsync(cause);
                }
            }
            catch (Exception ex)
            {
                CommonEventSource.Log.Info("Failed to close IoT Hub Client cleanly: " + ex.ToString(), this.ChannelId, this.Id);
            }
        }
        /// <summary>
        ///     Performs complete initialization of <see cref="MqttAdapter" /> based on received CONNECT packet.
        /// </summary>
        /// <param name="context"><see cref="IChannelHandlerContext" /> instance.</param>
        /// <param name="packet">CONNECT packet.</param>
        async void Connect(IChannelHandlerContext context, ConnectPacket packet)
        {
            bool connAckSent = false;

            Exception exception = null;

            try
            {
                if (!this.IsInState(StateFlags.WaitingForConnect))
                {
                    ShutdownOnError(context, ConnectProcessingScope, new ProtocolGatewayException(ErrorCode.DuplicateConnectReceived, "CONNECT has been received in current session already. Only one CONNECT is expected per session."));
                    return;
                }

                this.stateFlags = StateFlags.ProcessingConnect;
                this.identity   = await this.authProvider.GetAsync(packet.ClientId,
                                                                   packet.Username, packet.Password, context.Channel.RemoteAddress);

                if (!this.identity.IsAuthenticated)
                {
                    CommonEventSource.Log.Info("ClientNotAuthenticated", this.ChannelId, $"Client ID: {packet.ClientId}; Username: {packet.Username}");
                    connAckSent = true;
                    await Util.WriteMessageAsync(context, new ConnAckPacket
                    {
                        ReturnCode = ConnectReturnCode.RefusedNotAuthorized
                    });

                    PerformanceCounters.ConnectionFailedAuthPerSecond.Increment();
                    ShutdownOnError(context, ConnectProcessingScope, new ProtocolGatewayException(ErrorCode.AuthenticationFailed, "Authentication failed."));
                    return;
                }

                CommonEventSource.Log.Info("ClientAuthenticated", this.ChannelId, this.Id);

                this.messagingBridge = await this.messagingBridgeFactory(this.identity, this.lifetimeCancellation.Token);

                bool sessionPresent = await this.EstablishSessionStateAsync(packet.CleanSession);

                this.keepAliveTimeout = this.DeriveKeepAliveTimeout(context, packet);

                if (packet.HasWill)
                {
                    var will = new PublishPacket(packet.WillQualityOfService, false, packet.WillRetain);
                    will.TopicName  = packet.WillTopicName;
                    will.Payload    = packet.WillMessage;
                    this.willPacket = will;
                }

                connAckSent = true;
                await Util.WriteMessageAsync(context, new ConnAckPacket
                {
                    SessionPresent = sessionPresent,
                    ReturnCode     = ConnectReturnCode.Accepted
                });

                this.CompleteConnect(context);
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            if (exception != null)
            {
                if (!connAckSent)
                {
                    try
                    {
                        await Util.WriteMessageAsync(context, new ConnAckPacket
                        {
                            ReturnCode = ConnectReturnCode.RefusedServerUnavailable
                        });
                    }
                    catch (Exception ex)
                    {
                        if (CommonEventSource.Log.IsVerboseEnabled)
                        {
                            CommonEventSource.Log.Verbose("Error sending 'Server Unavailable' CONNACK:" + ex, this.ChannelId, this.Id);
                        }
                    }
                }

                ShutdownOnError(context, ConnectProcessingScope, exception);
            }
        }