mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-30 02:38:53 +08:00
Improve payload handling and allocation.
This commit is contained in:
@@ -79,24 +79,21 @@ namespace MQTTnet.Formatter
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
WriteWithLengthPrefix(Encoding.UTF8.GetBytes(value));
|
WriteWithLengthPrefix(Encoding.UTF8.GetBytes(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteWithLengthPrefix(byte[] value)
|
public void WriteWithLengthPrefix(byte[] value)
|
||||||
{
|
{
|
||||||
if (value == null) throw new ArgumentNullException(nameof(value));
|
if (value == null || value.Length == 0)
|
||||||
|
|
||||||
EnsureAdditionalCapacity(value.Length + 2);
|
|
||||||
|
|
||||||
if (value.Length == 0)
|
|
||||||
{
|
{
|
||||||
Write(ZeroTwoByteIntegerArray);
|
Write(ZeroTwoByteIntegerArray);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
EnsureAdditionalCapacity(value.Length + 2);
|
||||||
Write((ushort)value.Length);
|
Write((ushort)value.Length);
|
||||||
Write(value, 0, value.Length);
|
Write(value, 0, value.Length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(byte @byte)
|
public void Write(byte @byte)
|
||||||
@@ -131,7 +128,7 @@ namespace MQTTnet.Formatter
|
|||||||
Array.Copy(buffer, offset, _buffer, _offset, count);
|
Array.Copy(buffer, offset, _buffer, _offset, count);
|
||||||
IncreasePosition(count);
|
IncreasePosition(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Write(MqttPacketWriter propertyWriter)
|
public void Write(MqttPacketWriter propertyWriter)
|
||||||
{
|
{
|
||||||
if (propertyWriter == null) throw new ArgumentNullException(nameof(propertyWriter));
|
if (propertyWriter == null) throw new ArgumentNullException(nameof(propertyWriter));
|
||||||
|
|||||||
@@ -56,17 +56,17 @@ namespace MQTTnet.Formatter.V3
|
|||||||
case MqttControlPacketType.Connect: return DecodeConnectPacket(receivedMqttPacket.Body);
|
case MqttControlPacketType.Connect: return DecodeConnectPacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.ConnAck: return DecodeConnAckPacket(receivedMqttPacket.Body);
|
case MqttControlPacketType.ConnAck: return DecodeConnAckPacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.Disconnect: return new MqttDisconnectPacket();
|
case MqttControlPacketType.Disconnect: return new MqttDisconnectPacket();
|
||||||
case MqttControlPacketType.Publish: return DecodePublish(receivedMqttPacket);
|
case MqttControlPacketType.Publish: return DecodePublishPacket(receivedMqttPacket);
|
||||||
case MqttControlPacketType.PubAck: return DecodePubAck(receivedMqttPacket.Body);
|
case MqttControlPacketType.PubAck: return DecodePubAckPacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.PubRec: return DecodePubRec(receivedMqttPacket.Body);
|
case MqttControlPacketType.PubRec: return DecodePubRecPacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.PubRel: return DecodePubRel(receivedMqttPacket.Body);
|
case MqttControlPacketType.PubRel: return DecodePubRelPacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.PubComp: return DecodePubComp(receivedMqttPacket.Body);
|
case MqttControlPacketType.PubComp: return DecodePubCompPacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.PingReq: return new MqttPingReqPacket();
|
case MqttControlPacketType.PingReq: return new MqttPingReqPacket();
|
||||||
case MqttControlPacketType.PingResp: return new MqttPingRespPacket();
|
case MqttControlPacketType.PingResp: return new MqttPingRespPacket();
|
||||||
case MqttControlPacketType.Subscribe: return DecodeSubscribe(receivedMqttPacket.Body);
|
case MqttControlPacketType.Subscribe: return DecodeSubscribePacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.SubAck: return DecodeSubAck(receivedMqttPacket.Body);
|
case MqttControlPacketType.SubAck: return DecodeSubAckPacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.Unsubscibe: return DecodeUnsubscribe(receivedMqttPacket.Body);
|
case MqttControlPacketType.Unsubscibe: return DecodeUnsubscribePacket(receivedMqttPacket.Body);
|
||||||
case MqttControlPacketType.UnsubAck: return DecodeUnsubAck(receivedMqttPacket.Body);
|
case MqttControlPacketType.UnsubAck: return DecodeUnsubAckPacket(receivedMqttPacket.Body);
|
||||||
|
|
||||||
default: throw new MqttProtocolViolationException($"Packet type ({controlPacketType}) not supported.");
|
default: throw new MqttProtocolViolationException($"Packet type ({controlPacketType}) not supported.");
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodeUnsubAck(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodeUnsubAckPacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodePubComp(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodePubCompPacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodePubRel(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodePubRelPacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodePubRec(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodePubRecPacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodePubAck(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodePubAckPacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodeUnsubscribe(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodeUnsubscribePacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodeSubscribe(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodeSubscribePacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodePublish(ReceivedMqttPacket receivedMqttPacket)
|
private static MqttBasePacket DecodePublishPacket(ReceivedMqttPacket receivedMqttPacket)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(receivedMqttPacket.Body);
|
ThrowIfBodyIsEmpty(receivedMqttPacket.Body);
|
||||||
|
|
||||||
@@ -211,11 +211,15 @@ namespace MQTTnet.Formatter.V3
|
|||||||
PacketIdentifier = packetIdentifier,
|
PacketIdentifier = packetIdentifier,
|
||||||
Retain = retain,
|
Retain = retain,
|
||||||
Topic = topic,
|
Topic = topic,
|
||||||
Payload = receivedMqttPacket.Body.ReadRemainingData().ToArray(),
|
|
||||||
QualityOfServiceLevel = qualityOfServiceLevel,
|
QualityOfServiceLevel = qualityOfServiceLevel,
|
||||||
Dup = dup
|
Dup = dup
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!receivedMqttPacket.Body.EndOfStream)
|
||||||
|
{
|
||||||
|
packet.Payload = receivedMqttPacket.Body.ReadRemainingData().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +275,7 @@ namespace MQTTnet.Formatter.V3
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MqttBasePacket DecodeSubAck(MqttPacketBodyReader body)
|
private static MqttBasePacket DecodeSubAckPacket(MqttPacketBodyReader body)
|
||||||
{
|
{
|
||||||
ThrowIfBodyIsEmpty(body);
|
ThrowIfBodyIsEmpty(body);
|
||||||
|
|
||||||
|
|||||||
@@ -503,7 +503,10 @@ namespace MQTTnet.Formatter.V5
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.Payload = body.ReadRemainingData().ToArray();
|
if (!body.EndOfStream)
|
||||||
|
{
|
||||||
|
packet.Payload = body.ReadRemainingData().ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ namespace MQTTnet.Formatter.V5
|
|||||||
|
|
||||||
private static byte EncodeSubscribePacket(MqttSubscribePacket packet, MqttPacketWriter packetWriter)
|
private static byte EncodeSubscribePacket(MqttSubscribePacket packet, MqttPacketWriter packetWriter)
|
||||||
{
|
{
|
||||||
if (!packet.TopicFilters.Any()) throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.8.3-3].");
|
if (packet.TopicFilters?.Any() != true) throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.8.3-3].");
|
||||||
|
|
||||||
ThrowIfPacketIdentifierIsInvalid(packet);
|
ThrowIfPacketIdentifierIsInvalid(packet);
|
||||||
|
|
||||||
@@ -427,12 +427,9 @@ namespace MQTTnet.Formatter.V5
|
|||||||
|
|
||||||
private static byte EncodeSubAckPacket(MqttSubAckPacket packet, MqttPacketWriter packetWriter)
|
private static byte EncodeSubAckPacket(MqttSubAckPacket packet, MqttPacketWriter packetWriter)
|
||||||
{
|
{
|
||||||
ThrowIfPacketIdentifierIsInvalid(packet);
|
if (packet.ReasonCodes?.Any() != true) throw new MqttProtocolViolationException("At least one reason code must be set[MQTT - 3.8.3 - 3].");
|
||||||
|
|
||||||
if (packet.ReasonCodes == null || !packet.ReasonCodes.Any())
|
ThrowIfPacketIdentifierIsInvalid(packet);
|
||||||
{
|
|
||||||
throw new MqttProtocolViolationException("At least one reason code must be set[MQTT - 3.8.3 - 3].");
|
|
||||||
}
|
|
||||||
|
|
||||||
packetWriter.Write(packet.PacketIdentifier.Value);
|
packetWriter.Write(packet.PacketIdentifier.Value);
|
||||||
|
|
||||||
@@ -455,7 +452,7 @@ namespace MQTTnet.Formatter.V5
|
|||||||
|
|
||||||
private static byte EncodeUnsubscribePacket(MqttUnsubscribePacket packet, MqttPacketWriter packetWriter)
|
private static byte EncodeUnsubscribePacket(MqttUnsubscribePacket packet, MqttPacketWriter packetWriter)
|
||||||
{
|
{
|
||||||
if (!packet.TopicFilters.Any()) throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.10.3-2].");
|
if (packet.TopicFilters?.Any() != true) throw new MqttProtocolViolationException("At least one topic filter must be set [MQTT-3.10.3-2].");
|
||||||
|
|
||||||
ThrowIfPacketIdentifierIsInvalid(packet);
|
ThrowIfPacketIdentifierIsInvalid(packet);
|
||||||
|
|
||||||
@@ -479,13 +476,10 @@ namespace MQTTnet.Formatter.V5
|
|||||||
|
|
||||||
private static byte EncodeUnsubAckPacket(MqttUnsubAckPacket packet, MqttPacketWriter packetWriter)
|
private static byte EncodeUnsubAckPacket(MqttUnsubAckPacket packet, MqttPacketWriter packetWriter)
|
||||||
{
|
{
|
||||||
|
if (packet.ReasonCodes?.Any() != true) throw new MqttProtocolViolationException("At least one reason code must be set[MQTT - 3.8.3 - 3].");
|
||||||
|
|
||||||
ThrowIfPacketIdentifierIsInvalid(packet);
|
ThrowIfPacketIdentifierIsInvalid(packet);
|
||||||
|
|
||||||
if (packet.ReasonCodes == null || !packet.ReasonCodes.Any())
|
|
||||||
{
|
|
||||||
throw new MqttProtocolViolationException("At least one reason code must be set[MQTT - 3.8.3 - 3].");
|
|
||||||
}
|
|
||||||
|
|
||||||
packetWriter.Write(packet.PacketIdentifier.Value);
|
packetWriter.Write(packet.PacketIdentifier.Value);
|
||||||
|
|
||||||
var propertiesWriter = new MqttV500PropertiesWriter();
|
var propertiesWriter = new MqttV500PropertiesWriter();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace MQTTnet
|
|||||||
|
|
||||||
public bool Retain { get; set; }
|
public bool Retain { get; set; }
|
||||||
|
|
||||||
public List<MqttUserProperty> UserProperties { get; set; } = new List<MqttUserProperty>();
|
public List<MqttUserProperty> UserProperties { get; set; }
|
||||||
|
|
||||||
public string ContentType { get; set; }
|
public string ContentType { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -11,8 +10,6 @@ namespace MQTTnet
|
|||||||
{
|
{
|
||||||
public class MqttApplicationMessageBuilder
|
public class MqttApplicationMessageBuilder
|
||||||
{
|
{
|
||||||
private readonly List<MqttUserProperty> _userProperties = new List<MqttUserProperty>();
|
|
||||||
|
|
||||||
private MqttQualityOfServiceLevel _qualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce;
|
private MqttQualityOfServiceLevel _qualityOfServiceLevel = MqttQualityOfServiceLevel.AtMostOnce;
|
||||||
private string _topic;
|
private string _topic;
|
||||||
private byte[] _payload;
|
private byte[] _payload;
|
||||||
@@ -24,6 +21,7 @@ namespace MQTTnet
|
|||||||
private uint? _subscriptionIdentifier;
|
private uint? _subscriptionIdentifier;
|
||||||
private uint? _messageExpiryInterval;
|
private uint? _messageExpiryInterval;
|
||||||
private MqttPayloadFormatIndicator? _payloadFormatIndicator;
|
private MqttPayloadFormatIndicator? _payloadFormatIndicator;
|
||||||
|
private List<MqttUserProperty> _userProperties;
|
||||||
|
|
||||||
public MqttApplicationMessageBuilder WithTopic(string topic)
|
public MqttApplicationMessageBuilder WithTopic(string topic)
|
||||||
{
|
{
|
||||||
@@ -70,7 +68,7 @@ namespace MQTTnet
|
|||||||
|
|
||||||
if (payload.Length == 0)
|
if (payload.Length == 0)
|
||||||
{
|
{
|
||||||
_payload = new byte[0];
|
_payload = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -89,7 +87,7 @@ namespace MQTTnet
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
_payload = string.IsNullOrEmpty(payload) ? new byte[0] : Encoding.UTF8.GetBytes(payload);
|
_payload = string.IsNullOrEmpty(payload) ? null : Encoding.UTF8.GetBytes(payload);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,6 +126,11 @@ namespace MQTTnet
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public MqttApplicationMessageBuilder WithUserProperty(string name, string value)
|
public MqttApplicationMessageBuilder WithUserProperty(string name, string value)
|
||||||
{
|
{
|
||||||
|
if (_userProperties == null)
|
||||||
|
{
|
||||||
|
_userProperties = new List<MqttUserProperty>();
|
||||||
|
}
|
||||||
|
|
||||||
_userProperties.Add(new MqttUserProperty(name, value));
|
_userProperties.Add(new MqttUserProperty(name, value));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -205,7 +208,7 @@ namespace MQTTnet
|
|||||||
var applicationMessage = new MqttApplicationMessage
|
var applicationMessage = new MqttApplicationMessage
|
||||||
{
|
{
|
||||||
Topic = _topic,
|
Topic = _topic,
|
||||||
Payload = _payload ?? new byte[0],
|
Payload = _payload,
|
||||||
QualityOfServiceLevel = _qualityOfServiceLevel,
|
QualityOfServiceLevel = _qualityOfServiceLevel,
|
||||||
Retain = _retain,
|
Retain = _retain,
|
||||||
ContentType = _contentType,
|
ContentType = _contentType,
|
||||||
@@ -217,8 +220,11 @@ namespace MQTTnet
|
|||||||
PayloadFormatIndicator = _payloadFormatIndicator
|
PayloadFormatIndicator = _payloadFormatIndicator
|
||||||
};
|
};
|
||||||
|
|
||||||
applicationMessage.UserProperties.AddRange(_userProperties);
|
if (_userProperties?.Any() == true)
|
||||||
|
{
|
||||||
|
applicationMessage.UserProperties = _userProperties;
|
||||||
|
}
|
||||||
|
|
||||||
return applicationMessage;
|
return applicationMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
var saveIsRequired = false;
|
var saveIsRequired = false;
|
||||||
|
|
||||||
if (applicationMessage.Payload?.Length == 0)
|
if (applicationMessage.Payload?.Any() != true)
|
||||||
{
|
{
|
||||||
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
||||||
_logger.Verbose("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
_logger.Verbose("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||||
|
|||||||
Reference in New Issue
Block a user