Пример #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;
        }
Пример #2
0
        public MqttClientConnection(MqttConnectPacket connectPacket,
                                    IMqttChannelAdapter channelAdapter,
                                    MqttClientSession session,
                                    MqttConnectionValidatorContext connectionValidatorContext,
                                    IMqttServerOptions serverOptions,
                                    MqttClientSessionsManager sessionsManager,
                                    IMqttRetainedMessagesManager retainedMessagesManager,
                                    IMqttNetLogger logger)
        {
            Session                  = session ?? throw new ArgumentNullException(nameof(session));
            _serverOptions           = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
            _sessionsManager         = sessionsManager ?? throw new ArgumentNullException(nameof(sessionsManager));
            _retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));

            _channelAdapter             = channelAdapter ?? throw new ArgumentNullException(nameof(channelAdapter));
            _connectionValidatorContext = connectionValidatorContext ?? throw new ArgumentNullException(nameof(connectionValidatorContext));
            _dataConverter = _channelAdapter.PacketFormatterAdapter.DataConverter;
            _endpoint      = _channelAdapter.Endpoint;
            ConnectPacket  = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            _logger = logger.CreateScopedLogger(nameof(MqttClientConnection));

            _connectedTimestamp         = DateTime.UtcNow;
            LastPacketReceivedTimestamp = _connectedTimestamp;
            _lastNonKeepAlivePacketReceivedTimestamp = LastPacketReceivedTimestamp;
        }
Пример #3
0
        async Task <MqttConnectPacket> ReceiveConnectPacket(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
        {
            try
            {
                using (var timeoutToken = new CancellationTokenSource(_options.DefaultCommunicationTimeout))
                    using (var effectiveCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(timeoutToken.Token, cancellationToken))
                    {
                        var firstPacket = await channelAdapter.ReceivePacketAsync(effectiveCancellationToken.Token).ConfigureAwait(false);

                        if (firstPacket is MqttConnectPacket connectPacket)
                        {
                            return(connectPacket);
                        }
                    }
            }
            catch (OperationCanceledException)
            {
                _logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint);
            }
            catch (MqttCommunicationTimedOutException)
            {
                _logger.Warning("Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint);
            }

            _logger.Warning("Client '{0}': First received packet was no 'CONNECT' packet [MQTT-3.1.0-1].", channelAdapter.Endpoint);
            return(null);
        }
Пример #4
0
        public MqttClient(
            MqttConnectPacket connectPacket,
            IMqttChannelAdapter channelAdapter,
            MqttSession session,
            MqttServerOptions serverOptions,
            MqttServerEventContainer eventContainer,
            MqttClientSessionsManager sessionsManager,
            IMqttNetLogger logger)
        {
            _serverOptions   = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
            _eventContainer  = eventContainer;
            _sessionsManager = sessionsManager ?? throw new ArgumentNullException(nameof(sessionsManager));

            ChannelAdapter = channelAdapter ?? throw new ArgumentNullException(nameof(channelAdapter));
            Endpoint       = channelAdapter.Endpoint;

            Session        = session ?? throw new ArgumentNullException(nameof(session));
            _connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _logger = logger.WithSource(nameof(MqttClient));
        }
Пример #5
0
        async Task <MqttClientAuthenticateResult> AuthenticateAsync(IMqttChannelAdapter channelAdapter, MqttApplicationMessage willApplicationMessage, CancellationToken cancellationToken)
        {
            MqttClientAuthenticateResult result;

            try
            {
                var connectPacket = channelAdapter.PacketFormatterAdapter.DataConverter.CreateConnectPacket(
                    willApplicationMessage,
                    Options);

                var connAckPacket = await SendAndReceiveAsync <MqttConnAckPacket>(connectPacket, cancellationToken).ConfigureAwait(false);

                result = channelAdapter.PacketFormatterAdapter.DataConverter.CreateClientConnectResult(connAckPacket);
            }
            catch (Exception exception)
            {
                throw new MqttConnectingFailedException($"Error while authenticating. {exception.Message}", exception, null);
            }

            if (result.ResultCode != MqttClientConnectResultCode.Success)
            {
                throw new MqttConnectingFailedException($"Connecting with MQTT server failed ({result.ResultCode}).", null, result);
            }

            _logger.Verbose("Authenticated MQTT connection with server established.");

            return(result);
        }
Пример #6
0
        public async Task <MqttClientConnectResult> ConnectAsync(IMqttClientOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }
            if (options.ChannelOptions == null)
            {
                throw new ArgumentException("ChannelOptions are not set.");
            }

            ThrowIfConnected("It is not allowed to connect with a server after the connection is established.");

            try
            {
                Options = options;

                _packetIdentifierProvider.Reset();
                _packetDispatcher.Reset();

                _cancellationTokenSource = new CancellationTokenSource();
                _disconnectGate          = 0;
                _adapter = _adapterFactory.CreateClientAdapter(options, _logger);

                _logger.Verbose($"Trying to connect with server ({Options.ChannelOptions}).");
                await _adapter.ConnectAsync(Options.CommunicationTimeout, _cancellationTokenSource.Token).ConfigureAwait(false);

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

                StartReceivingPackets(_cancellationTokenSource.Token);

                var connectResponse = await AuthenticateAsync(options.WillMessage, _cancellationTokenSource.Token).ConfigureAwait(false);

                _logger.Verbose("MQTT connection with server established.");

                _sendTracker.Restart();

                if (Options.KeepAlivePeriod != TimeSpan.Zero)
                {
                    StartSendingKeepAliveMessages(_cancellationTokenSource.Token);
                }

                IsConnected = true;
                Connected?.Invoke(this, new MqttClientConnectedEventArgs(connectResponse.IsSessionPresent));

                _logger.Info("Connected.");
                return(new MqttClientConnectResult(connectResponse.IsSessionPresent));
            }
            catch (Exception exception)
            {
                _logger.Error(exception, "Error while connecting with server.");

                if (!DisconnectIsPending())
                {
                    await DisconnectInternalAsync(null, exception).ConfigureAwait(false);
                }

                throw;
            }
        }
Пример #7
0
        private Task HandleIncomingPublishPacketAsync(IMqttChannelAdapter adapter, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
        {
            var applicationMessage = publishPacket.ToApplicationMessage();

            switch (applicationMessage.QualityOfServiceLevel)
            {
            case MqttQualityOfServiceLevel.AtMostOnce:
            {
                return(ApplicationMessageReceivedCallback?.Invoke(this, applicationMessage));
            }

            case MqttQualityOfServiceLevel.AtLeastOnce:
            {
                return(HandleIncomingPublishPacketWithQoS1(adapter, applicationMessage, publishPacket, cancellationToken));
            }

            case MqttQualityOfServiceLevel.ExactlyOnce:
            {
                return(HandleIncomingPublishPacketWithQoS2(adapter, applicationMessage, publishPacket, cancellationToken));
            }

            default:
            {
                throw new MqttCommunicationException("Received a not supported QoS level.");
            }
            }
        }
Пример #8
0
        private void HandleIncomingPublishPacket(IMqttChannelAdapter adapter, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
        {
            switch (publishPacket.QualityOfServiceLevel)
            {
            case MqttQualityOfServiceLevel.AtMostOnce:
            {
                HandleIncomingPublishPacketWithQoS0(publishPacket);
                break;
            }

            case MqttQualityOfServiceLevel.AtLeastOnce:
            {
                HandleIncomingPublishPacketWithQoS1(adapter, publishPacket, cancellationToken);
                break;
            }

            case MqttQualityOfServiceLevel.ExactlyOnce:
            {
                HandleIncomingPublishPacketWithQoS2(adapter, publishPacket, cancellationToken);
                break;
            }

            default:
            {
                throw new MqttCommunicationException("Received a not supported QoS level.");
            }
            }
        }
Пример #9
0
        private async Task ReceivePacketsAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
        {
            try
            {
                while (!cancellationToken.IsCancellationRequested)
                {
                    var packet = await adapter.ReceivePacketAsync(TimeSpan.Zero, cancellationToken).ConfigureAwait(false);

                    KeepAliveMonitor.PacketReceived(packet);
                    await ProcessReceivedPacketAsync(adapter, packet, cancellationToken).ConfigureAwait(false);
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (MqttCommunicationException exception)
            {
                _logger.Warning <MqttClientSession>(exception, "Client '{0}': Communication exception while processing client packets.", ClientId);
                await StopAsync().ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                _logger.Error <MqttClientSession>(exception, "Client '{0}': Unhandled exception while processing client packets.", ClientId);
                await StopAsync().ConfigureAwait(false);
            }
        }
Пример #10
0
        public async Task StopAsync()
        {
            try
            {
                if (_cancellationTokenSource == null)
                {
                    return;
                }

                _cancellationTokenSource?.Cancel(false);
                _cancellationTokenSource?.Dispose();
                _cancellationTokenSource = null;

                if (_adapter != null)
                {
                    await _adapter.DisconnectAsync(_options.DefaultCommunicationTimeout).ConfigureAwait(false);

                    _adapter = null;
                }

                _logger.Info <MqttClientSession>("Client '{0}': Session stopped.", ClientId);
            }
            finally
            {
                var willMessage = _willMessage;
                if (willMessage != null)
                {
                    _willMessage = null; // clear willmessage so it is send just once
                    await ApplicationMessageReceivedCallback(this, willMessage).ConfigureAwait(false);
                }
            }
        }
Пример #11
0
        public MqttClientConnection(
            MqttConnectPacket connectPacket,
            IMqttChannelAdapter channelAdapter,
            MqttClientSession session,
            IMqttServerOptions serverOptions,
            MqttClientSessionsManager sessionsManager,
            IMqttRetainedMessagesManager retainedMessagesManager,
            Func <Task> onStart,
            Func <MqttClientDisconnectType, Task> onStop,
            IMqttNetLogger logger)
        {
            Session                  = session ?? throw new ArgumentNullException(nameof(session));
            _serverOptions           = serverOptions ?? throw new ArgumentNullException(nameof(serverOptions));
            _sessionsManager         = sessionsManager ?? throw new ArgumentNullException(nameof(sessionsManager));
            _retainedMessagesManager = retainedMessagesManager ?? throw new ArgumentNullException(nameof(retainedMessagesManager));
            _onStart                 = onStart ?? throw new ArgumentNullException(nameof(onStart));
            _onStop                  = onStop ?? throw new ArgumentNullException(nameof(onStop));

            _channelAdapter = channelAdapter ?? throw new ArgumentNullException(nameof(channelAdapter));
            _dataConverter  = _channelAdapter.PacketFormatterAdapter.DataConverter;
            _endpoint       = _channelAdapter.Endpoint;
            ConnectPacket   = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));

            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }
            _logger = logger.CreateScopedLogger(nameof(MqttClientConnection));

            _keepAliveMonitor = new MqttClientKeepAliveMonitor(ConnectPacket.ClientId, () => StopAsync(), logger);

            _connectedTimestamp                      = DateTime.UtcNow;
            _lastPacketReceivedTimestamp             = _connectedTimestamp;
            _lastNonKeepAlivePacketReceivedTimestamp = _lastPacketReceivedTimestamp;
        }
Пример #12
0
        public async Task CleanUpClient(string clientId, IMqttChannelAdapter channelAdapter, MqttClientDisconnectType disconnectType)
        {
            if (clientId != null)
            {
                // in case it is a takeover _connections already contains the new connection
                if (disconnectType != MqttClientDisconnectType.Takeover)
                {
                    lock (_connections)
                    {
                        _connections.Remove(clientId);
                    }

                    if (!_options.EnablePersistentSessions)
                    {
                        await DeleteSessionAsync(clientId).ConfigureAwait(false);
                    }
                }
            }

            await SafeCleanupChannelAsync(channelAdapter).ConfigureAwait(false);

            if (clientId != null)
            {
                await _eventDispatcher.SafeNotifyClientDisconnectedAsync(clientId, disconnectType).ConfigureAwait(false);
            }
        }
Пример #13
0
        public async Task HandleClientConnectionAsync(IMqttChannelAdapter channelAdapter, CancellationToken cancellationToken)
        {
            try
            {
                MqttConnectPacket connectPacket;
                try
                {
                    using (var timeoutToken = new CancellationTokenSource(_options.DefaultCommunicationTimeout))
                    {
                        var firstPacket = await channelAdapter.ReceivePacketAsync(timeoutToken.Token).ConfigureAwait(false);

                        connectPacket = firstPacket as MqttConnectPacket;
                        if (connectPacket == null)
                        {
                            _logger.Warning(null,
                                            "Client '{0}': First received packet was no 'CONNECT' packet [MQTT-3.1.0-1].",
                                            channelAdapter.Endpoint);

                            return;
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    _logger.Warning(null, "Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint);
                    return;
                }
                catch (MqttCommunicationTimedOutException)
                {
                    _logger.Warning(null, "Client '{0}': Connected but did not sent a CONNECT packet.", channelAdapter.Endpoint);
                    return;
                }

                var connectionValidatorContext = await ValidateConnectionAsync(connectPacket, channelAdapter).ConfigureAwait(false);

                if (connectionValidatorContext.ReasonCode != MqttConnectReasonCode.Success)
                {
                    // Send failure response here without preparing a session. The result for a successful connect
                    // will be sent from the session itself.
                    var connAckPacket = channelAdapter.PacketFormatterAdapter.DataConverter.CreateConnAckPacket(connectionValidatorContext);
                    await channelAdapter.SendPacketAsync(connAckPacket, cancellationToken).ConfigureAwait(false);

                    return;
                }

                var connection = await CreateClientConnectionAsync(connectPacket, connectionValidatorContext, channelAdapter).ConfigureAwait(false);

                await _eventDispatcher.SafeNotifyClientConnectedAsync(connectPacket.ClientId).ConfigureAwait(false);

                await connection.RunAsync().ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
            }
            catch (Exception exception)
            {
                _logger.Error(exception, exception.Message);
            }
        }
Пример #14
0
        private Task HandleIncomingPubRelPacketAsync(IMqttChannelAdapter adapter, MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
        {
            var response = new MqttPubCompPacket {
                PacketIdentifier = pubRelPacket.PacketIdentifier
            };

            return(adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, response));
        }
Пример #15
0
        async Task <MqttClientConnection> CreateClientConnection(
            MqttConnectPacket connectPacket,
            MqttConnAckPacket connAckPacket,
            IMqttChannelAdapter channelAdapter,
            IDictionary <object, object> sessionItems)
        {
            MqttClientConnection connection;

            using (await _createConnectionSyncRoot.WaitAsync(CancellationToken.None).ConfigureAwait(false))
            {
                MqttClientSession session;
                lock (_clientSessions)
                {
                    if (!_clientSessions.TryGetValue(connectPacket.ClientId, out session))
                    {
                        _logger.Verbose("Created a new session for client '{0}'.", connectPacket.ClientId);
                        session = CreateSession(connectPacket.ClientId, sessionItems);
                    }
                    else
                    {
                        if (connectPacket.CleanSession)
                        {
                            _logger.Verbose("Deleting existing session of client '{0}'.", connectPacket.ClientId);
                            session = CreateSession(connectPacket.ClientId, sessionItems);
                        }
                        else
                        {
                            _logger.Verbose("Reusing existing session of client '{0}'.", connectPacket.ClientId);
                            connAckPacket.IsSessionPresent = true;
                        }
                    }

                    _clientSessions[connectPacket.ClientId] = session;
                }

                MqttClientConnection existingConnection;

                lock (_clientConnections)
                {
                    _clientConnections.TryGetValue(connectPacket.ClientId, out existingConnection);
                    connection = CreateConnection(connectPacket, channelAdapter, session);

                    _clientConnections[connectPacket.ClientId] = connection;
                }

                if (existingConnection != null)
                {
                    await _eventDispatcher.SafeNotifyClientDisconnectedAsync(existingConnection.ClientId,
                                                                             MqttClientDisconnectType.Takeover, existingConnection.Endpoint);

                    existingConnection.IsTakenOver = true;
                    await existingConnection.StopAsync(MqttClientDisconnectReason.SessionTakenOver)
                    .ConfigureAwait(false);
                }
            }

            return(connection);
        }
Пример #16
0
        private void Cleanup()
        {
            _backgroundCancellationTokenSource?.Cancel(false);
            _backgroundCancellationTokenSource?.Dispose();
            _backgroundCancellationTokenSource = null;

            _adapter?.Dispose();
            _adapter = null;
        }
Пример #17
0
        public Task HandleClientConnectionAsync(IMqttChannelAdapter clientAdapter)
        {
            if (clientAdapter is null)
            {
                throw new ArgumentNullException(nameof(clientAdapter));
            }

            return(HandleClientConnectionAsync(clientAdapter, _cancellationToken));
        }
Пример #18
0
        public void Dispose()
        {
            _cancellationTokenSource?.Cancel(false);
            _cancellationTokenSource?.Dispose();
            _cancellationTokenSource = null;

            _adapter?.Dispose();
            _adapter = null;
        }
Пример #19
0
        public static Task SendPacketsAsync(this IMqttChannelAdapter adapter, TimeSpan timeout, CancellationToken cancellationToken, params MqttBasePacket[] packets)
        {
            if (adapter == null)
            {
                throw new ArgumentNullException(nameof(adapter));
            }

            return(adapter.SendPacketsAsync(timeout, cancellationToken, packets));
        }
Пример #20
0
        private async Task HandleIncomingPublishPacketWithQoS1(IMqttChannelAdapter adapter, MqttApplicationMessage applicationMessage, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
        {
            await _sessionsManager.DispatchApplicationMessageAsync(this, applicationMessage).ConfigureAwait(false);

            var response = new MqttPubAckPacket {
                PacketIdentifier = publishPacket.PacketIdentifier
            };
            await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, response).ConfigureAwait(false);
        }
        private async Task SendNextQueuedPacketAsync(IMqttChannelAdapter adapter, CancellationToken cancellationToken)
        {
            MqttBasePacket packet = null;

            try
            {
                await _queueWaitSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);

                if (!_queue.TryDequeue(out packet))
                {
                    throw new InvalidOperationException(); // should not happen
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[] { packet }).ConfigureAwait(false);

                _logger.Trace <MqttClientPendingMessagesQueue>("Enqueued packet sent (ClientId: {0}).", _clientSession.ClientId);
            }
            catch (Exception exception)
            {
                if (exception is MqttCommunicationTimedOutException)
                {
                    _logger.Warning <MqttClientPendingMessagesQueue>(exception, "Sending publish packet failed due to timeout (ClientId: {0}).", _clientSession.ClientId);
                }
                else if (exception is MqttCommunicationException)
                {
                    _logger.Warning <MqttClientPendingMessagesQueue>(exception, "Sending publish packet failed due to communication exception (ClientId: {0}).", _clientSession.ClientId);
                }
                else if (exception is OperationCanceledException)
                {
                }
                else
                {
                    _logger.Error <MqttClientPendingMessagesQueue>(exception, "Sending publish packet failed (ClientId: {0}).", _clientSession.ClientId);
                }

                if (packet is MqttPublishPacket publishPacket)
                {
                    if (publishPacket.QualityOfServiceLevel > MqttQualityOfServiceLevel.AtMostOnce)
                    {
                        publishPacket.Dup = true;
                        _queue.Enqueue(packet);
                        _queueWaitSemaphore.Release();
                    }
                }

                if (!cancellationToken.IsCancellationRequested)
                {
                    await _clientSession.StopAsync().ConfigureAwait(false);
                }
            }
        }
Пример #22
0
        private Task ProcessReceivedPacketAsync(IMqttChannelAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken)
        {
            if (packet is MqttPublishPacket publishPacket)
            {
                return(HandleIncomingPublishPacketAsync(adapter, publishPacket, cancellationToken));
            }

            if (packet is MqttPingReqPacket)
            {
                return(adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[] { new MqttPingRespPacket() }));
            }

            if (packet is MqttPubRelPacket pubRelPacket)
            {
                return(HandleIncomingPubRelPacketAsync(adapter, pubRelPacket, cancellationToken));
            }

            if (packet is MqttPubRecPacket pubRecPacket)
            {
                var responsePacket = new MqttPubRelPacket
                {
                    PacketIdentifier = pubRecPacket.PacketIdentifier
                };

                return(adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[] { responsePacket }));
            }

            if (packet is MqttPubAckPacket || packet is MqttPubCompPacket)
            {
                // Discard message.
                return(Task.FromResult(0));
            }

            if (packet is MqttSubscribePacket subscribePacket)
            {
                return(HandleIncomingSubscribePacketAsync(adapter, subscribePacket, cancellationToken));
            }

            if (packet is MqttUnsubscribePacket unsubscribePacket)
            {
                return(HandleIncomingUnsubscribePacketAsync(adapter, unsubscribePacket, cancellationToken));
            }

            if (packet is MqttDisconnectPacket)
            {
                return(StopAsync(true));
            }

            if (packet is MqttConnectPacket)
            {
                return(StopAsync());
            }

            _logger.Warning <MqttClientSession>("Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
            return(StopAsync());
        }
Пример #23
0
        private async Task HandleIncomingPublishPacketWithQoS2(IMqttChannelAdapter adapter, MqttApplicationMessage applicationMessage, MqttPublishPacket publishPacket, CancellationToken cancellationToken)
        {
            // QoS 2 is implement as method "B" [4.3.3 QoS 2: Exactly once delivery]
            await _sessionsManager.DispatchApplicationMessageAsync(this, applicationMessage).ConfigureAwait(false);

            var response = new MqttPubRecPacket {
                PacketIdentifier = publishPacket.PacketIdentifier
            };
            await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, response).ConfigureAwait(false);
        }
Пример #24
0
 async Task SafeCleanupChannelAsync(IMqttChannelAdapter channelAdapter)
 {
     try
     {
         await channelAdapter.DisconnectAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
     }
     catch (Exception exception)
     {
         _logger.Error(exception, "Error while disconnecting client channel.");
     }
 }
Пример #25
0
        Task OnClientAcceptedAsync(IMqttChannelAdapter channelAdapter)
        {
            var clientHandler = ClientHandler;

            if (clientHandler == null)
            {
                return(Task.FromResult(0));
            }

            return(clientHandler(channelAdapter));
        }
Пример #26
0
 MqttClientConnection CreateConnection(MqttConnectPacket connectPacket, IMqttChannelAdapter channelAdapter,
                                       MqttClientSession session)
 {
     return(new MqttClientConnection(
                connectPacket,
                channelAdapter,
                session,
                _options,
                this,
                _rootLogger));
 }
Пример #27
0
        private Task HandleIncomingPubRelPacketAsync(IMqttChannelAdapter adapter, MqttPubRelPacket pubRelPacket, CancellationToken cancellationToken)
        {
            lock (_unacknowledgedPublishPackets)
            {
                _unacknowledgedPublishPackets.Remove(pubRelPacket.PacketIdentifier);
            }

            return(adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttPubCompPacket {
                PacketIdentifier = pubRelPacket.PacketIdentifier
            }));
        }
Пример #28
0
        public async Task DisconnectAsync(CancellationToken cancellationToken)
        {
            if (_adapter == null)
            {
                return;
            }

            await SafeDisconnect(cancellationToken).ConfigureAwait(false);

            _adapter = null;
        }
 MqttClientConnection CreateConnection(MqttConnectPacket connectPacket, IMqttChannelAdapter channelAdapter, MqttClientSession session, MqttConnectionValidatorContext connectionValidatorContext)
 {
     return(new MqttClientConnection(
                connectPacket,
                channelAdapter,
                session,
                connectionValidatorContext,
                _options,
                this,
                _retainedMessagesManager,
                _rootLogger));
 }
Пример #30
0
        private async Task HandleIncomingSubscribePacketAsync(IMqttChannelAdapter adapter, MqttSubscribePacket subscribePacket, CancellationToken cancellationToken)
        {
            var subscribeResult = await SubscriptionsManager.SubscribeAsync(subscribePacket).ConfigureAwait(false);

            await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new[] { subscribeResult.ResponsePacket }).ConfigureAwait(false);

            if (subscribeResult.CloseConnection)
            {
                await StopAsync().ConfigureAwait(false);
            }

            await EnqueueSubscribedRetainedMessagesAsync(subscribePacket.TopicFilters).ConfigureAwait(false);
        }