示例#1
0
        public void MqttPacketReader_EmptyStream()
        {
            var memStream = new MemoryStream();
            var header    = MqttPacketReader.ReadHeaderAsync(memStream, CancellationToken.None).GetAwaiter().GetResult();

            Assert.IsNull(header);
        }
示例#2
0
        private static async Task <ReceivedMqttPacket> ReceiveAsync(Stream stream, CancellationToken cancellationToken)
        {
            var header = MqttPacketReader.ReadHeaderFromSource(stream, cancellationToken);

            if (header == null)
            {
                return(null);
            }

            if (header.BodyLength == 0)
            {
                return(new ReceivedMqttPacket(header, EmptyBody));
            }

            var body = new byte[header.BodyLength];

            var offset = 0;

            do
            {
                var readBytesCount = await stream.ReadAsync(body, offset, body.Length - offset, cancellationToken).ConfigureAwait(false);

                offset += readBytesCount;
            } while (offset < header.BodyLength);

            return(new ReceivedMqttPacket(header, body));
        }
示例#3
0
        public void MqttPacketReader_EmptyStream()
        {
            var memStream = new MemoryStream();
            var header    = MqttPacketReader.ReadHeaderFromSource(memStream, CancellationToken.None);

            Assert.IsNull(header);
        }
示例#4
0
        public void MqttPacketReader_EmptyStream()
        {
            var fixedHeader      = new byte[2];
            var singleByteBuffer = new byte[1];

            MqttPacketReader.ReadFixedHeaderAsync(new TestMqttChannel(new MemoryStream()), fixedHeader, singleByteBuffer, CancellationToken.None).GetAwaiter().GetResult();
        }
        public async Task MqttPacketReader_EmptyStream()
        {
            var fixedHeader = new byte[2];
            var reader      = new MqttPacketReader(new TestMqttChannel(new MemoryStream()));
            var readResult  = await reader.ReadFixedHeaderAsync(fixedHeader, CancellationToken.None);

            Assert.IsTrue(readResult.ConnectionClosed);
        }
示例#6
0
        public MqttChannelAdapter(IMqttChannel channel, MqttPacketFormatterAdapter packetFormatterAdapter, IMqttNetChildLogger logger)
        {
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            _channel = channel ?? throw new ArgumentNullException(nameof(channel));
            PacketFormatterAdapter = packetFormatterAdapter ?? throw new ArgumentNullException(nameof(packetFormatterAdapter));

            _packetReader = new MqttPacketReader(_channel);

            _logger = logger.CreateChildLogger(nameof(MqttChannelAdapter));
        }
示例#7
0
        public void Serialize_LargePacket()
        {
            var serializer = new MqttPacketSerializer {
                ProtocolVersion = MqttProtocolVersion.V311
            };

            const int payloadLength = 80000;

            var payload = new byte[payloadLength];

            var value = 0;

            for (var i = 0; i < payloadLength; i++)
            {
                if (value > 255)
                {
                    value = 0;
                }

                payload[i] = (byte)value;
            }

            var publishPacket = new MqttPublishPacket
            {
                Topic   = "abcdefghijklmnopqrstuvwxyz0123456789",
                Payload = payload
            };

            var buffer      = serializer.Serialize(publishPacket);
            var testChannel = new TestMqttChannel(new MemoryStream(buffer.Array, buffer.Offset, buffer.Count));

            var header = MqttPacketReader.ReadFixedHeaderAsync(
                testChannel,
                new byte[2],
                new byte[1],
                CancellationToken.None).GetAwaiter().GetResult();

            var eof = buffer.Offset + buffer.Count;

            var receivedPacket = new ReceivedMqttPacket(
                header.Flags,
                new MqttPacketBodyReader(buffer.Array, eof - header.RemainingLength, buffer.Count + buffer.Offset));

            var packet = (MqttPublishPacket)serializer.Deserialize(receivedPacket);

            Assert.AreEqual(publishPacket.Topic, packet.Topic);
            Assert.IsTrue(publishPacket.Payload.SequenceEqual(packet.Payload));
        }
示例#8
0
        private async Task <ReceivedMqttPacket> ReceiveAsync(CancellationToken cancellationToken)
        {
            var fixedHeader = await MqttPacketReader.ReadFixedHeaderAsync(_channel, _fixedHeaderBuffer, _singleByteBuffer, cancellationToken).ConfigureAwait(false);

            try
            {
                ReadingPacketStarted?.Invoke(this, EventArgs.Empty);

                if (fixedHeader.RemainingLength == 0)
                {
                    return(new ReceivedMqttPacket(fixedHeader.Flags, null));
                }

                var body       = new byte[fixedHeader.RemainingLength];
                var bodyOffset = 0;
                var chunkSize  = Math.Min(ReadBufferSize, fixedHeader.RemainingLength);

                do
                {
                    var bytesLeft = body.Length - bodyOffset;
                    if (chunkSize > bytesLeft)
                    {
                        chunkSize = bytesLeft;
                    }

#if WINDOWS_UWP
                    var readBytes = await _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false);
#else
                    // async/await is not used to avoid the overhead of context switches. We assume that the reamining data
                    // has been sent from the sender directly after the initial bytes.
                    //var readBytes = _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult();
                    var readBytes = AsyncContext.Run(async() => await _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false));
#endif

                    cancellationToken.ThrowIfCancellationRequested();
                    ExceptionHelper.ThrowIfGracefulSocketClose(readBytes);

                    bodyOffset += readBytes;
                } while (bodyOffset < body.Length);

                return(new ReceivedMqttPacket(fixedHeader.Flags, new MqttPacketBodyReader(body, 0, body.Length)));
            }
            finally
            {
                ReadingPacketCompleted?.Invoke(this, EventArgs.Empty);
            }
        }
        private MqttProtocolVersion DeserializeAndDetectVersion(MqttPacketFormatterAdapter adapter, byte[] buffer)
        {
            using (var headerStream = new MemoryStream(buffer))
            {
                var channel     = new TestMqttChannel(headerStream);
                var fixedHeader = new byte[2];

                var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;

                using (var bodyStream = new MemoryStream(buffer, (int)headerStream.Position, (int)header.RemainingLength))
                {
                    var reader = ReaderFactory(bodyStream.ToArray());
                    var packet = new ReceivedMqttPacket(header.Flags, reader, 0);
                    adapter.DetectProtocolVersion(packet);
                    return(adapter.ProtocolVersion);
                }
            }
        }
示例#10
0
        private async Task <MqttReceivedPacket> ReceiveAsync(CancellationToken cancellationToken)
        {
            var fixedHeader = await MqttPacketReader.ReadFixedHeaderAsync(_channel, _fixedHeaderBuffer, _singleByteBuffer, cancellationToken).ConfigureAwait(false);

            try
            {
                ReadingPacketStarted?.Invoke(this, EventArgs.Empty);

                if (fixedHeader.RemainingLength == 0)
                {
                    return(new MqttReceivedPacket(fixedHeader.Flags, null));
                }

                var body       = new byte[fixedHeader.RemainingLength];
                var bodyOffset = 0;
                var chunkSize  = Math.Min(ReadBufferSize, fixedHeader.RemainingLength);

                do
                {
                    var bytesLeft = body.Length - bodyOffset;
                    if (chunkSize > bytesLeft)
                    {
                        chunkSize = bytesLeft;
                    }


                    //async/await不用于避免上下文切换的开销。我们假设扩孔数据已从发件人直接发送到初始字节之后。
                    var readBytes = _channel.ReadAsync(body, bodyOffset, chunkSize, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult();


                    cancellationToken.ThrowIfCancellationRequested();
                    ExceptionHelper.ThrowIfGracefulSocketClose(readBytes);

                    bodyOffset += readBytes;
                } while (bodyOffset < body.Length);

                return(new MqttReceivedPacket(fixedHeader.Flags, new MqttPacketBodyReader(body, 0, body.Length)));
            }
            finally
            {
                ReadingPacketCompleted?.Invoke(this, EventArgs.Empty);
            }
        }
        private static void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value)
        {
            var serializer = new MqttPacketSerializer();

            var buffer1 = serializer.Serialize(packet);

            using (var headerStream = new MemoryStream(Join(buffer1)))
            {
                var header = MqttPacketReader.ReadHeaderFromSource(headerStream, CancellationToken.None);

                using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.BodyLength))
                {
                    var deserializedPacket = serializer.Deserialize(header, bodyStream.ToArray());
                    var buffer2            = serializer.Serialize(deserializedPacket);

                    Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
                }
            }
        }
示例#12
0
        private static async Task <ReceivedMqttPacket> ReceiveAsync(Stream stream, CancellationToken cancellationToken)
        {
            var header = await MqttPacketReader.ReadHeaderAsync(stream, cancellationToken).ConfigureAwait(false);

            if (header == null)
            {
                return(null);
            }

            if (header.BodyLength == 0)
            {
                return(new ReceivedMqttPacket(header, new MemoryStream(new byte[0], false)));
            }

            var body = header.BodyLength <= ReadBufferSize ? new MemoryStream(header.BodyLength) : new MemoryStream();

            var buffer = new byte[ReadBufferSize];

            while (body.Length < header.BodyLength)
            {
                var bytesLeft = header.BodyLength - (int)body.Length;
                if (bytesLeft > buffer.Length)
                {
                    bytesLeft = buffer.Length;
                }

                var readBytesCount = await stream.ReadAsync(buffer, 0, bytesLeft, cancellationToken).ConfigureAwait(false);

                // Check if the client closed the connection before sending the full body.
                if (readBytesCount == 0)
                {
                    throw new MqttCommunicationException("Connection closed while reading remaining packet body.");
                }

                // Here is no need to await because internally only an array is used and no real I/O operation is made.
                // Using async here will only generate overhead.
                body.Write(buffer, 0, readBytesCount);
            }

            body.Seek(0L, SeekOrigin.Begin);

            return(new ReceivedMqttPacket(header, body));
        }
示例#13
0
        public void Deserialize_10000_Messages()
        {
            var channel          = new BenchmarkMqttChannel(_serializedPacket);
            var fixedHeader      = new byte[2];
            var singleByteBuffer = new byte[1];

            for (var i = 0; i < 10000; i++)
            {
                channel.Reset();

                var header = MqttPacketReader.ReadFixedHeaderAsync(channel, fixedHeader, singleByteBuffer, CancellationToken.None).GetAwaiter().GetResult();

                var receivedPacket = new ReceivedMqttPacket(
                    header.Flags,
                    new MqttPacketBodyReader(_serializedPacket.Array, _serializedPacket.Count - header.RemainingLength, _serializedPacket.Array.Length));

                _serializer.Deserialize(receivedPacket);
            }
        }
示例#14
0
        private static void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
        {
            var serializer = new MqttPacketSerializer {
                ProtocolVersion = protocolVersion
            };

            var buffer1 = serializer.Serialize(packet);

            using (var headerStream = new MemoryStream(Join(buffer1)))
            {
                var header = MqttPacketReader.ReadHeaderAsync(headerStream, CancellationToken.None).GetAwaiter().GetResult();

                using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.BodyLength))
                {
                    var deserializedPacket = serializer.Deserialize(header, bodyStream);
                    var buffer2            = serializer.Serialize(deserializedPacket);

                    Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
                }
            }
        }
示例#15
0
        private T Roundtrip <T>(T packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
            where T : MqttBasePacket
        {
            var writer = WriterFactory();

            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);

            var buffer1 = serializer.Encode(packet);

            using (var headerStream = new MemoryStream(Join(buffer1)))
            {
                var channel     = new TestMqttChannel(headerStream);
                var fixedHeader = new byte[2];

                var header = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;

                using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, (int)header.RemainingLength))
                {
                    var reader = ReaderFactory(bodyStream.ToArray());
                    return((T)serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0)));
                }
            }
        }
示例#16
0
        private static T Roundtrip <T>(T packet, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
            where T : MqttBasePacket
        {
            var serializer = new MqttPacketSerializer {
                ProtocolVersion = protocolVersion
            };

            var buffer1 = serializer.Serialize(packet);

            using (var headerStream = new MemoryStream(Join(buffer1)))
            {
                var channel          = new TestMqttChannel(headerStream);
                var fixedHeader      = new byte[2];
                var singleByteBuffer = new byte[1];

                var header = MqttPacketReader.ReadFixedHeaderAsync(channel, fixedHeader, singleByteBuffer, CancellationToken.None).GetAwaiter().GetResult();

                using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
                {
                    return((T)serializer.Deserialize(new ReceivedMqttPacket(header.Flags, new MqttPacketBodyReader(bodyStream.ToArray(), 0, (int)bodyStream.Length))));
                }
            }
        }
示例#17
0
        private void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
        {
            var writer = WriterFactory();

            var serializer = MqttPacketFormatterAdapter.GetMqttPacketFormatter(protocolVersion, writer);

            var buffer1 = serializer.Encode(packet);

            using (var headerStream = new MemoryStream(Join(buffer1)))
            {
                var channel     = new TestMqttChannel(headerStream);
                var fixedHeader = new byte[2];
                var header      = new MqttPacketReader(channel).ReadFixedHeaderAsync(fixedHeader, CancellationToken.None).GetAwaiter().GetResult().FixedHeader;

                using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
                {
                    var reader             = ReaderFactory(bodyStream.ToArray());
                    var deserializedPacket = serializer.Decode(new ReceivedMqttPacket(header.Flags, reader, 0));
                    var buffer2            = serializer.Encode(deserializedPacket);

                    Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
                }
            }
        }
示例#18
0
        private static void DeserializeAndCompare(MqttBasePacket packet, string expectedBase64Value, MqttProtocolVersion protocolVersion = MqttProtocolVersion.V311)
        {
            var serializer = new MqttPacketSerializer {
                ProtocolVersion = protocolVersion
            };

            var buffer1 = serializer.Serialize(packet);

            using (var headerStream = new MemoryStream(Join(buffer1)))
            {
                var channel          = new TestMqttChannel(headerStream);
                var fixedHeader      = new byte[2];
                var singleByteBuffer = new byte[1];
                var header           = MqttPacketReader.ReadFixedHeaderAsync(channel, fixedHeader, singleByteBuffer, CancellationToken.None).GetAwaiter().GetResult();

                using (var bodyStream = new MemoryStream(Join(buffer1), (int)headerStream.Position, header.RemainingLength))
                {
                    var deserializedPacket = serializer.Deserialize(new ReceivedMqttPacket(header.Flags, new MqttPacketBodyReader(bodyStream.ToArray(), 0, (int)bodyStream.Length)));
                    var buffer2            = serializer.Serialize(deserializedPacket);

                    Assert.AreEqual(expectedBase64Value, Convert.ToBase64String(Join(buffer2)));
                }
            }
        }