public async Task HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken) { MqttClient client = null; try { var connectPacket = await ReceiveConnectPacket(channelAdapter, cancellationToken).ConfigureAwait(false); if (connectPacket == null) { // Nothing was received in time etc. return; } var validatingConnectionEventArgs = await ValidateConnection(connectPacket, channelAdapter).ConfigureAwait(false); var connAckPacket = _packetFactories.ConnAck.Create(validatingConnectionEventArgs); if (validatingConnectionEventArgs.ReasonCode != MqttConnectReasonCode.Success) { // Send failure response here without preparing a connection and session! await channelAdapter.SendPacketAsync(connAckPacket, cancellationToken).ConfigureAwait(false); return; } // Pass connAckPacket so that IsSessionPresent flag can be set if the client session already exists. client = await CreateClientConnection(connectPacket, connAckPacket, channelAdapter, validatingConnectionEventArgs).ConfigureAwait(false); await client.SendPacketAsync(connAckPacket, cancellationToken).ConfigureAwait(false); if (_eventContainer.ClientConnectedEvent.HasHandlers) { var eventArgs = new ClientConnectedEventArgs { ClientId = connectPacket.ClientId, UserName = connectPacket.Username, ProtocolVersion = channelAdapter.PacketFormatterAdapter.ProtocolVersion, Endpoint = channelAdapter.Endpoint }; await _eventContainer.ClientConnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false); } await client.RunAsync().ConfigureAwait(false); } catch (OperationCanceledException) { } catch (Exception exception) { _logger.Error(exception, exception.Message); } finally { if (client != null) { if (client.Id != null) { // in case it is a takeover _clientConnections already contains the new connection if (!client.IsTakenOver) { lock (_clients) { _clients.Remove(client.Id); } if (!_options.EnablePersistentSessions || !client.Session.IsPersistent) { await DeleteSessionAsync(client.Id).ConfigureAwait(false); } } } var endpoint = client.Endpoint; if (client.Id != null && !client.IsTakenOver && _eventContainer.ClientDisconnectedEvent.HasHandlers) { var eventArgs = new ClientDisconnectedEventArgs { ClientId = client.Id, DisconnectType = client.IsCleanDisconnect ? MqttClientDisconnectType.Clean : MqttClientDisconnectType.NotClean, Endpoint = endpoint }; await _eventContainer.ClientDisconnectedEvent.InvokeAsync(eventArgs).ConfigureAwait(false); } } using (var timeout = new CancellationTokenSource(_options.DefaultCommunicationTimeout)) { await channelAdapter.DisconnectAsync(timeout.Token).ConfigureAwait(false); } } }