Пример #1
0
        private async Task OpenMethodsReceiverLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, CancellationToken cancellationToken)
        {
            if (_methodReceivingLink == null ||
                _methodReceivingLink.IsClosing())
            {
                _methodReceivingLink?.SafeClose();

                _methodReceivingLink = await amqpIotSession
                                       .OpenMethodsReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, cancellationToken)
                                       .ConfigureAwait(false);

                if (_methodReceiverLinkDisconnected == null)
                {
                    _methodReceiverLinkDisconnected = (obj, arg) =>
                    {
                        amqpIotSession.SafeClose();
                    };
                }

                _methodReceivingLink.Closed += _methodReceiverLinkDisconnected;

                _methodReceivingLink.RegisterMethodListener(OnMethodReceived);
                if (Logging.IsEnabled)
                {
                    Logging.Associate(this, _methodReceivingLink, nameof(_methodReceivingLink));
                }
            }
        }
Пример #2
0
        public async Task EnableEventReceiveAsync(CancellationToken cancellationToken)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(EnableEventReceiveAsync));
            }

            AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(cancellationToken).ConfigureAwait(false);

            try
            {
                await _eventReceivingLinkSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP event receiver links are open.");
            }

            try
            {
                if (_eventReceivingLink == null ||
                    _eventReceivingLink.IsClosing())
                {
                    _eventReceivingLink?.SafeClose();

                    _eventReceivingLink = await amqpIotSession
                                          .OpenEventsReceiverLinkAsync(_deviceIdentity, cancellationToken)
                                          .ConfigureAwait(false);

                    if (_eventReceiverLinkDisconnected == null)
                    {
                        _eventReceiverLinkDisconnected = (obj, arg) =>
                        {
                            amqpIotSession.SafeClose();
                        };
                    }

                    _messageReceivingLink.Closed += _eventReceiverLinkDisconnected;
                    _eventReceivingLink.RegisterEventListener(OnEventsReceived);
                    if (Logging.IsEnabled)
                    {
                        Logging.Associate(this, this, _eventReceivingLink, nameof(EnableEventReceiveAsync));
                    }
                }
            }
            finally
            {
                _eventReceivingLinkSemaphore.Release();
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(EnableEventReceiveAsync));
                }
            }
        }
Пример #3
0
        private async Task OpenTwinReceiverLinkAsync(AmqpIotSession amqpIotSession, string correlationIdSuffix, TimeSpan timeout)
        {
            if (_twinReceivingLink == null || _twinReceivingLink.IsClosing())
            {
                _twinReceivingLink?.SafeClose();

                _twinReceivingLink = await amqpIotSession
                                     .OpenTwinReceiverLinkAsync(_deviceIdentity, correlationIdSuffix, timeout)
                                     .ConfigureAwait(false);

                _twinReceivingLink.Closed += (obj, arg) =>
                {
                    amqpIotSession.SafeClose();
                };
                _twinReceivingLink.RegisterTwinListener(OnDesiredPropertyReceived);
                Logging.Associate(this, _twinReceivingLink, nameof(_twinReceivingLink));
            }
        }
Пример #4
0
        private async Task EnsureMessageReceivingLinkIsOpenAsync(TimeSpan timeout, bool enableCallback = false)
        {
            if (_closed)
            {
                throw new IotHubException("Device is now offline.", false);
            }

            Logging.Enter(this, timeout, nameof(EnsureMessageReceivingLinkIsOpenAsync));

            AmqpIotSession amqpIotSession = await EnsureSessionIsOpenAsync(timeout).ConfigureAwait(false);

            bool enteredSemaphore = await _messageReceivingLinkSemaphore.WaitAsync(timeout).ConfigureAwait(false);

            if (!enteredSemaphore)
            {
                throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP message receiver links are open.");
            }

            try
            {
                if (_messageReceivingLink == null || _messageReceivingLink.IsClosing())
                {
                    _messageReceivingLink?.SafeClose();

                    _messageReceivingLink = await amqpIotSession.OpenMessageReceiverLinkAsync(_deviceIdentity, timeout).ConfigureAwait(false);

                    _messageReceivingLink.Closed += (obj, arg) =>
                    {
                        amqpIotSession.SafeClose();
                    };
                    Logging.Associate(this, this, _messageReceivingLink, nameof(EnsureMessageReceivingLinkIsOpenAsync));
                }

                if (enableCallback)
                {
                    _messageReceivingLink.RegisterReceiveMessageListener(OnDeviceMessageReceived);
                }
            }
            finally
            {
                _messageReceivingLinkSemaphore.Release();
                Logging.Exit(this, timeout, nameof(EnsureMessageReceivingLinkIsOpenAsync));
            }
        }
Пример #5
0
        public async Task DisableMethodsAsync(TimeSpan timeout)
        {
            Logging.Enter(this, timeout, nameof(DisableMethodsAsync));

            Debug.Assert(_methodSendingLink != null);
            Debug.Assert(_methodReceivingLink != null);

            bool enteredSemaphore = await _methodLinkSemaphore.WaitAsync(timeout).ConfigureAwait(false);

            if (!enteredSemaphore)
            {
                throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP method sender and receiver links are closed.");
            }

            try
            {
                ICollection <Task> tasks = new List <Task>();
                if (_methodReceivingLink != null)
                {
                    tasks.Add(_methodReceivingLink.CloseAsync(timeout));
                }

                if (_methodSendingLink != null)
                {
                    tasks.Add(_methodSendingLink.CloseAsync(timeout));
                }

                if (tasks.Count > 0)
                {
                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    _methodReceivingLink = null;
                    _methodSendingLink   = null;
                }
            }
            finally
            {
                Logging.Exit(this, timeout, nameof(DisableMethodsAsync));
                _methodLinkSemaphore.Release();
            }
        }
Пример #6
0
        public async Task DisableMethodsAsync(CancellationToken cancellationToken)
        {
            if (Logging.IsEnabled)
            {
                Logging.Enter(this, nameof(DisableMethodsAsync));
            }

            Debug.Assert(_methodSendingLink != null);
            Debug.Assert(_methodReceivingLink != null);

            try
            {
                await _methodLinkSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (OperationCanceledException)
            {
                throw new TimeoutException("Failed to enter the semaphore required for ensuring that AMQP method sender and receiver links are closed.");
            }

            // These event handlers are in place for network drop cases and will try to close the session that this
            // link belongs to, but that isn't necessary when the client is deliberately closing just the link.
            if (_methodReceiverLinkDisconnected != null)
            {
                _methodReceivingLink.Closed -= _methodReceiverLinkDisconnected;
            }

            if (_methodSenderLinkDisconnected != null)
            {
                _methodSendingLink.Closed -= _methodSenderLinkDisconnected;
            }

            try
            {
                ICollection <Task> tasks = new List <Task>(2);
                if (_methodReceivingLink != null)
                {
                    tasks.Add(_methodReceivingLink.CloseAsync(cancellationToken));
                }

                if (_methodSendingLink != null)
                {
                    tasks.Add(_methodSendingLink.CloseAsync(cancellationToken));
                }

                if (tasks.Count > 0)
                {
                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    _methodReceivingLink = null;
                    _methodSendingLink   = null;
                }
            }
            finally
            {
                if (Logging.IsEnabled)
                {
                    Logging.Exit(this, nameof(DisableMethodsAsync));
                }
                _methodLinkSemaphore.Release();
            }
        }