async void ShutdownOnReceiveError(string exception) { this.publishPubAckProcessor.Abort(); foreach (var publishProcessor in this.publishProcessors) { publishProcessor.Value.Abort(); } this.publishPubRecProcessor.Abort(); this.pubRelPubCompProcessor.Abort(); IMqttMessagingBridge bridge = this.messagingBridge; if (bridge != null) { this.messagingBridge = null; try { await bridge.DisposeAsync(); } catch (Exception ex) { CommonEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString()); } } ShutdownOnError(this.capturedContext, "Receive", exception); }
async void CloseIotHubConnection(IChannelHandlerContext context, PublishPacket will) { if (!this.ConnectedToHub) { // 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); IMqttMessagingBridge hub = this.messagingBridge; this.messagingBridge = null; await hub.DisposeAsync(); } catch (Exception ex) { CommonEventSource.Log.Info("Failed to close IoT Hub Client cleanly.", ex.ToString()); } }
/// <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, "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) { connAckSent = true; await Util.WriteMessageAsync(context, new ConnAckPacket { ReturnCode = ConnectReturnCode.RefusedNotAuthorized }); PerformanceCounters.ConnectionFailedAuthPerSecond.Increment(); ShutdownOnError(context, "Authentication failed."); return; } this.messagingBridge = await this.messagingBridgeFactory(this.identity); bool sessionPresent = await this.EstablishSessionStateAsync(packet.CleanSession); this.keepAliveTimeout = this.DeriveKeepAliveTimeout(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.ToString()); } } } ShutdownOnError(context, "CONNECT", exception); } }