Example #1
0
        public async Task ConnectAsync(IMqttClientOptions options, CancellationToken cancellationToken)
        {
            if (options is null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (_adapter != null)
            {
                throw new InvalidOperationException("Low level MQTT client is already connected. Disconnect first before connecting again.");
            }

            var newAdapter = _clientAdapterFactory.CreateClientAdapter(options);

            try
            {
                _logger.Verbose($"Trying to connect with server '{options.ChannelOptions}' (Timeout={options.CommunicationTimeout}).");
                await newAdapter.ConnectAsync(options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);

                _logger.Verbose("Connection with server established.");

                _options = options;
            }
            catch (Exception)
            {
                _adapter?.Dispose();
                throw;
            }

            _adapter = newAdapter;
        }
Example #2
0
        public void Dispose()
        {
            _cancellationTokenSource?.Dispose();
            _cancellationTokenSource = null;

            _adapter?.Dispose();
        }
Example #3
0
        private void Cleanup()
        {
            _backgroundCancellationTokenSource?.Cancel(false);
            _backgroundCancellationTokenSource?.Dispose();
            _backgroundCancellationTokenSource = null;

            _adapter?.Dispose();
            _adapter = null;
        }
Example #4
0
        public void Dispose()
        {
            _backgroundCancellationTokenSource?.Cancel(false);
            _backgroundCancellationTokenSource?.Dispose();
            _backgroundCancellationTokenSource = null;

            _adapter?.Dispose();
            _adapter = null;
        }
Example #5
0
        void Cleanup()
        {
            _backgroundCancellationTokenSource?.Cancel(false);
            _backgroundCancellationTokenSource?.Dispose();
            _backgroundCancellationTokenSource = null;

            _publishPacketReceiverQueue?.Dispose();
            _publishPacketReceiverQueue = null;

            _adapter?.Dispose();
        }
Example #6
0
 async Task SafeDisconnect(CancellationToken cancellationToken)
 {
     try
     {
         await _adapter.DisconnectAsync(_options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
     }
     catch (Exception exception)
     {
         _logger.Error(exception, "Error while disconnecting.");
     }
     finally
     {
         _adapter.Dispose();
     }
 }
        private void TryDisposeAdapter(IMqttChannelAdapter adapter)
        {
            if (adapter == null)
            {
                return;
            }

            try
            {
                adapter.ReadingPacketStarted   -= OnAdapterReadingPacketStarted;
                adapter.ReadingPacketCompleted -= OnAdapterReadingPacketCompleted;

                adapter.Dispose();
            }
            catch (Exception exception)
            {
                _logger.Error(exception, "Error while disposing channel adapter.");
            }
        }
Example #8
0
        async Task Cleanup(IMqttChannelAdapter clientAdapter)
        {
            try
            {
                await clientAdapter.DisconnectAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                _logger.Error(exception, "Error while disconnecting channel adapter.");
            }

            try
            {
                clientAdapter.Dispose();
            }
            catch (Exception exception)
            {
                _logger.Error(exception, "Error while disposing channel adapter.");
            }
        }
        private async Task RunSession(IMqttChannelAdapter clientAdapter, CancellationToken cancellationToken)
        {
            var clientId           = string.Empty;
            var wasCleanDisconnect = false;

            try
            {
                var firstPacket = await clientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, cancellationToken).ConfigureAwait(false);

                if (firstPacket == null)
                {
                    return;
                }

                if (!(firstPacket is MqttConnectPacket connectPacket))
                {
                    throw new MqttProtocolViolationException("The first packet from a client must be a 'CONNECT' packet [MQTT-3.1.0-1].");
                }

                clientId = connectPacket.ClientId;

                // Switch to the required protocol version before sending any response.
                clientAdapter.PacketSerializer.ProtocolVersion = connectPacket.ProtocolVersion;

                var connectReturnCode = ValidateConnection(connectPacket, clientAdapter);
                if (connectReturnCode != MqttConnectReturnCode.ConnectionAccepted)
                {
                    await clientAdapter.SendPacketAsync(
                        new MqttConnAckPacket
                    {
                        ConnectReturnCode = connectReturnCode
                    },
                        cancellationToken).ConfigureAwait(false);

                    return;
                }

                var result        = PrepareClientSession(connectPacket);
                var clientSession = result.Session;

                await clientAdapter.SendPacketAsync(
                    new MqttConnAckPacket
                {
                    ConnectReturnCode = connectReturnCode,
                    IsSessionPresent  = result.IsExistingSession
                },
                    cancellationToken).ConfigureAwait(false);

                Server.OnClientConnected(clientId);

                wasCleanDisconnect = await clientSession.RunAsync(connectPacket, clientAdapter).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception exception)
            {
                _logger.Error(exception, exception.Message);
            }
            finally
            {
                try
                {
                    await clientAdapter.DisconnectAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false);

                    clientAdapter.Dispose();
                }
                catch (Exception exception)
                {
                    _logger.Error(exception, exception.Message);
                }

                if (!_options.EnablePersistentSessions)
                {
                    DeleteSession(clientId);
                }

                Server.OnClientDisconnected(clientId, wasCleanDisconnect);
            }
        }
Example #10
0
        public async Task RunSessionAsync(IMqttChannelAdapter clientAdapter, CancellationToken cancellationToken)
        {
            var clientId                    = string.Empty;
            var wasCleanDisconnect          = false;
            MqttClientSession clientSession = null;

            try
            {
                if (!(await clientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, cancellationToken)
                      .ConfigureAwait(false) is MqttConnectPacket connectPacket))
                {
                    throw new MqttProtocolViolationException(
                              "The first packet from a client must be a 'CONNECT' packet [MQTT-3.1.0-1].");
                }

                clientId = connectPacket.ClientId;

                // Switch to the required protocol version before sending any response.
                clientAdapter.PacketSerializer.ProtocolVersion = connectPacket.ProtocolVersion;

                var connectReturnCode = ValidateConnection(connectPacket);
                if (connectReturnCode != MqttConnectReturnCode.ConnectionAccepted)
                {
                    await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[]
                    {
                        new MqttConnAckPacket
                        {
                            ConnectReturnCode = connectReturnCode
                        }
                    }).ConfigureAwait(false);

                    return;
                }

                var result = await GetOrCreateClientSessionAsync(connectPacket).ConfigureAwait(false);

                clientSession = result.Session;

                await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[]
                {
                    new MqttConnAckPacket
                    {
                        ConnectReturnCode = connectReturnCode,
                        IsSessionPresent  = result.IsExistingSession
                    }
                }).ConfigureAwait(false);

                ClientConnectedCallback?.Invoke(new ConnectedMqttClient
                {
                    ClientId        = clientId,
                    ProtocolVersion = clientAdapter.PacketSerializer.ProtocolVersion
                });

                wasCleanDisconnect = await clientSession.RunAsync(connectPacket, clientAdapter).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception exception)
            {
                _logger.Error <MqttClientSessionsManager>(exception, exception.Message);
            }
            finally
            {
                try
                {
                    await clientAdapter.DisconnectAsync(_options.DefaultCommunicationTimeout).ConfigureAwait(false);

                    clientAdapter.Dispose();
                }
                catch (Exception exception)
                {
                    _logger.Error <MqttClientSessionsManager>(exception, exception.Message);
                }

                ClientDisconnectedCallback?.Invoke(new ConnectedMqttClient
                {
                    ClientId                   = clientId,
                    ProtocolVersion            = clientAdapter.PacketSerializer.ProtocolVersion,
                    PendingApplicationMessages = clientSession?.PendingMessagesQueue.Count ?? 0
                },
                                                   wasCleanDisconnect);
            }
        }
Example #11
0
 public void Dispose()
 {
     _adapter?.Dispose();
 }