Beispiel #1
0
        public void Dispatch(MqttBasePacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            ushort identifier = 0;

            if (packet is IMqttPacketWithIdentifier packetWithIdentifier && packetWithIdentifier.PacketIdentifier.HasValue)
            {
                identifier = packetWithIdentifier.PacketIdentifier.Value;
            }

            var type = packet.GetType();
            var key  = new Tuple <ushort, Type>(identifier, type);

            if (_awaiters.TryRemove(key, out var awaiter))
            {
                Task.Run(() => awaiter.TrySetResult(packet)); // Task.Run fixes a dead lock. Without this the client only receives one message.
                return;
            }

            throw new InvalidOperationException($"Packet of type '{type.Name}' not handled or dispatched.");
        }
Beispiel #2
0
        public void Dispatch(MqttBasePacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            var type = packet.GetType();

            if (packet is IMqttPacketWithIdentifier withIdentifier)
            {
                if (_packetByResponseTypeAndIdentifier.TryGetValue(type, out var byid))
                {
                    if (byid.TryRemove(withIdentifier.PacketIdentifier, out var tcs))
                    {
                        tcs.TrySetResult(packet);
                        return;
                    }
                }
            }
            else if (_packetByResponseType.TryRemove(type, out var tcs))
            {
                tcs.TrySetResult(packet);
                return;
            }

            throw new InvalidOperationException($"Packet of type '{type.Name}' not handled or dispatched.");
        }
Beispiel #3
0
        public void Dispatch(MqttBasePacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            if (packet is MqttDisconnectPacket disconnectPacket)
            {
                foreach (var packetAwaiter in _awaiters)
                {
                    packetAwaiter.Value.Fail(new MqttUnexpectedDisconnectReceivedException(disconnectPacket));
                }

                return;
            }

            ushort identifier = 0;

            if (packet is IMqttPacketWithIdentifier packetWithIdentifier && packetWithIdentifier.PacketIdentifier > 0)
            {
                identifier = packetWithIdentifier.PacketIdentifier;
            }

            var type = packet.GetType();
            var key  = new Tuple <ushort, Type>(identifier, type);

            if (_awaiters.TryRemove(key, out var awaiter))
            {
                awaiter.Complete(packet);
                return;
            }

            throw new MqttProtocolViolationException($"Received packet '{packet}' at an unexpected time.");
        }
Beispiel #4
0
        public void Dispatch(MqttBasePacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            var type = packet.GetType();

            if (_awaiters.TryGetValue(type, out var byId))
            {
                ushort?identifier = 0;
                if (packet is IMqttPacketWithIdentifier packetWithIdentifier)
                {
                    identifier = packetWithIdentifier.PacketIdentifier;
                }

                if (byId.TryRemove(identifier.Value, out var tcs))
                {
                    tcs.TrySetResult(packet);
                    return;
                }
            }

            throw new InvalidOperationException($"Packet of type '{type.Name}' not handled or dispatched.");
        }
        public bool TryDispatch(MqttBasePacket packet)
        {
            if (packet == null)
            {
                throw new ArgumentNullException(nameof(packet));
            }

            ushort identifier = 0;

            if (packet is IMqttPacketWithIdentifier packetWithIdentifier)
            {
                identifier = packetWithIdentifier.PacketIdentifier;
            }

            var packetType = packet.GetType();
            var awaitables = new List <IMqttPacketAwaitable>();

            lock (_awaitables)
            {
                for (var i = _awaitables.Count - 1; i >= 0; i--)
                {
                    var entry = _awaitables[i];

                    // Note: The PingRespPacket will also arrive here and has NO identifier but there
                    // is code which waits for it. So the code must be able to deal with filters which
                    // are referring to the type only (identifier is 0)!
                    if (entry.Filter.Type != packetType || entry.Filter.Identifier != identifier)
                    {
                        continue;
                    }

                    awaitables.Add(entry);
                    _awaitables.RemoveAt(i);
                }
            }

            foreach (var matchingEntry in awaitables)
            {
                matchingEntry.Complete(packet);
            }

            return(awaitables.Count > 0);
        }
Beispiel #6
0
        async Task <TResponsePacket> SendAndReceiveAsync <TResponsePacket>(MqttBasePacket requestPacket, CancellationToken cancellationToken) where TResponsePacket : MqttBasePacket
        {
            cancellationToken.ThrowIfCancellationRequested();

            ushort identifier = 0;

            if (requestPacket is IMqttPacketWithIdentifier packetWithIdentifier && packetWithIdentifier.PacketIdentifier > 0)
            {
                identifier = packetWithIdentifier.PacketIdentifier;
            }

            using (var packetAwaiter = _packetDispatcher.AddAwaiter <TResponsePacket>(identifier))
            {
                try
                {
                    _sendTracker.Restart();

                    await _adapter.SendPacketAsync(requestPacket, Options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    _logger.Warning(e, "Error when sending request packet ({0}).", requestPacket.GetType().Name);
                    packetAwaiter.Cancel();
                }

                try
                {
                    return(await packetAwaiter.WaitOneAsync(Options.CommunicationTimeout).ConfigureAwait(false));
                }
                catch (Exception exception)
                {
                    if (exception is MqttCommunicationTimedOutException)
                    {
                        _logger.Warning(null, "Timeout while waiting for response packet ({0}).", typeof(TResponsePacket).Name);
                    }

                    throw;
                }
            }
        }
Beispiel #7
0
 public void AssertIsConnectPacket(MqttBasePacket packet)
 {
     Assert.AreEqual(packet.GetType(), typeof(MqttConnectPacket));
 }
        static void ThrowIfPacketIdentifierIsInvalid(ushort packetIdentifier, MqttBasePacket packet)
        {
            // SUBSCRIBE, UNSUBSCRIBE, and PUBLISH(in cases where QoS > 0) Control Packets MUST contain a non-zero 16 - bit Packet Identifier[MQTT - 2.3.1 - 1].

            if (packetIdentifier == 0)
            {
                throw new MqttProtocolViolationException($"Packet identifier is not set for {packet.GetType().Name}.");
            }
        }