Example #1
0
        public async Task DisconnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            try
            {
                if (timeout == TimeSpan.Zero)
                {
                    await _channel.DisconnectAsync(cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    await MqttTaskTimeout.WaitAsync(
                        t => _channel.DisconnectAsync(t), timeout, cancellationToken).ConfigureAwait(false);
                }
            }
            catch (Exception exception)
            {
                if (IsWrappedException(exception))
                {
                    throw;
                }

                WrapException(exception);
            }
        }
Example #2
0
        public async Task TimeoutAfterCompleteInTime()
        {
            var result = await MqttTaskTimeout.WaitAsync(
                ct => Task.Delay(TimeSpan.FromMilliseconds(100), ct).ContinueWith(t => 5, ct),
                TimeSpan.FromMilliseconds(500), CancellationToken.None);

            Assert.AreEqual(5, result);
        }
        public async Task <MqttBasePacket> ReceivePacketAsync(TimeSpan timeout, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();

            try
            {
                ReceivedMqttPacket receivedMqttPacket;
                if (timeout == TimeSpan.Zero)
                {
                    receivedMqttPacket = await ReceiveAsync(cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    receivedMqttPacket = await MqttTaskTimeout.WaitAsync(ReceiveAsync, timeout, cancellationToken).ConfigureAwait(false);
                }

                if (receivedMqttPacket == null || cancellationToken.IsCancellationRequested)
                {
                    return(null);
                }

                Interlocked.Add(ref _bytesSent, receivedMqttPacket.TotalLength);

                if (PacketFormatterAdapter.ProtocolVersion == MqttProtocolVersion.Unknown)
                {
                    PacketFormatterAdapter.DetectProtocolVersion(receivedMqttPacket);
                }

                var packet = PacketFormatterAdapter.Decode(receivedMqttPacket);
                if (packet == null)
                {
                    throw new MqttProtocolViolationException("Received malformed packet.");
                }

                _logger.Verbose("RX ({0} bytes) <<< {1}", receivedMqttPacket.TotalLength, packet);

                return(packet);
            }
            catch (OperationCanceledException)
            {
            }
            catch (ObjectDisposedException)
            {
            }
            catch (Exception exception)
            {
                if (IsWrappedException(exception))
                {
                    throw;
                }

                WrapException(exception);
            }

            return(null);
        }
        async Task ConnectInternalAsync(CancellationToken cancellationToken)
        {
            _webSocket.Error        += OnError;
            _webSocket.DataReceived += OnDataReceived;

            var taskCompletionSource = new TaskCompletionSource <Exception>();

            void ErrorHandler(object sender, ErrorEventArgs e)
            {
                taskCompletionSource.TrySetResult(e.Exception);
            }

            void SuccessHandler(object sender, EventArgs e)
            {
                taskCompletionSource.TrySetResult(null);
            }

            try
            {
                _webSocket.Opened += SuccessHandler;
                _webSocket.Error  += ErrorHandler;

#pragma warning disable AsyncFixer02 // Long-running or blocking operations inside an async method
                _webSocket.Open();
#pragma warning restore AsyncFixer02 // Long-running or blocking operations inside an async method

                var exception = await MqttTaskTimeout.WaitAsync(c =>
                {
                    c.Register(() => taskCompletionSource.TrySetCanceled());
                    return(taskCompletionSource.Task);
                }, _clientOptions.CommunicationTimeout, cancellationToken).ConfigureAwait(false);

                if (exception != null)
                {
                    if (exception is AuthenticationException authenticationException)
                    {
                        throw new MqttCommunicationException(authenticationException.InnerException);
                    }

                    if (exception is OperationCanceledException)
                    {
                        throw new MqttCommunicationTimedOutException();
                    }

                    throw new MqttCommunicationException(exception);
                }
            }
            catch (OperationCanceledException)
            {
                throw new MqttCommunicationTimedOutException();
            }
            finally
            {
                _webSocket.Opened -= SuccessHandler;
                _webSocket.Error  -= ErrorHandler;
            }
        }
        public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();
            cancellationToken.ThrowIfCancellationRequested();

            try
            {
                await _writerSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
            }
            catch (ObjectDisposedException)
            {
                throw new OperationCanceledException();
            }

            try
            {
                var packetData = PacketFormatterAdapter.Encode(packet);

                if (timeout == TimeSpan.Zero)
                {
                    await _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, cancellationToken).ConfigureAwait(false);
                }
                else
                {
                    await MqttTaskTimeout.WaitAsync(
                        t => _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, t), timeout, cancellationToken).ConfigureAwait(false);
                }

                Interlocked.Add(ref _bytesReceived, packetData.Count);

                _logger.Verbose("TX ({0} bytes) >>> {1}", packetData.Count, packet);
            }
            catch (Exception exception)
            {
                if (IsWrappedException(exception))
                {
                    throw;
                }

                WrapException(exception);
            }
            finally
            {
                PacketFormatterAdapter.FreeBuffer();

                try
                {
                    _writerSemaphore.Release();
                }
                catch (ObjectDisposedException)
                {
                    throw new OperationCanceledException();
                }
            }
        }
Example #6
0
        public async Task TimeoutAfterMemoryUsage()
        {
            var tasks = Enumerable.Range(0, 100000)
                        .Select(i =>
            {
                return(MqttTaskTimeout.WaitAsync(ct => Task.Delay(TimeSpan.FromMilliseconds(1), ct),
                                                 TimeSpan.FromMinutes(1), CancellationToken.None));
            });

            await Task.WhenAll(tasks);

            AssertIsLess(3_000_000, GC.GetTotalMemory(true));
        }
        public async Task TimeoutAfterWithInnerException()
        {
            try
            {
                await MqttTaskTimeout.WaitAsync(ct => Task.Run(() =>
                {
                    var iis = new int[0];
                    iis[1]  = 0;
                }, ct), TimeSpan.FromSeconds(1), CancellationToken.None);

                Assert.Fail();
            }
            catch (Exception e)
            {
                Assert.IsTrue(e is IndexOutOfRangeException);
            }
        }
Example #8
0
        public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ThrowIfDisposed();

            using (await _syncRoot.WaitAsync(cancellationToken).ConfigureAwait(false))
            {
                // Check for cancellation here again because "WaitAsync" might take some time.
                cancellationToken.ThrowIfCancellationRequested();

                try
                {
                    var packetData = PacketFormatterAdapter.Encode(packet);

                    if (timeout == TimeSpan.Zero)
                    {
                        await _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        await MqttTaskTimeout.WaitAsync(
                            t => _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, t), timeout, cancellationToken).ConfigureAwait(false);
                    }

                    Interlocked.Add(ref _bytesReceived, packetData.Count);

                    _logger.Verbose("TX ({0} bytes) >>> {1}", packetData.Count, packet);
                }
                catch (Exception exception)
                {
                    if (IsWrappedException(exception))
                    {
                        throw;
                    }

                    WrapAndThrowException(exception);
                }
                finally
                {
                    PacketFormatterAdapter.FreeBuffer();
                }
            }
        }
 public async Task TimeoutAfterWithResult()
 {
     await MqttTaskTimeout.WaitAsync(
         ct => Task.Delay(TimeSpan.FromMilliseconds(500), ct).ContinueWith(t => 5, ct),
         TimeSpan.FromMilliseconds(100), CancellationToken.None);
 }
 public async Task TimeoutAfter()
 {
     await MqttTaskTimeout.WaitAsync(ct => Task.Delay(TimeSpan.FromMilliseconds(500), ct),
                                     TimeSpan.FromMilliseconds(100), CancellationToken.None);
 }