提交 844c70e5 编写于 作者: C Christian

Add support for custom session items for injected application messages

上级 f623f9d9
......@@ -5,3 +5,4 @@
* [Server] Exposed MQTT v5 sent properties from the affected client in _ClientDisconnectedAsync_ event.
* [Server] Fixed wrong client ID passed to _InterceptingUnsubscriptionEventArgs_ (#1631, thanks to @ghord).
* [Server] Exposed socket settings for TCP keep alive in TCP options (#1544).
* [Server] Exposed server session items at server level and allow custom session items for injected application messages (#1638).
......@@ -82,12 +82,7 @@ namespace MQTTnet.Adapter
{
try
{
var eventArgs = new InspectMqttPacketEventArgs
{
Buffer = buffer,
Direction = direction
};
var eventArgs = new InspectMqttPacketEventArgs(direction, buffer);
_asyncEvent.InvokeAsync(eventArgs).GetAwaiter().GetResult();
}
catch (Exception exception)
......
......@@ -9,9 +9,18 @@ namespace MQTTnet.Client
{
public sealed class MqttClientPublishResult
{
public MqttClientPublishResult(ushort? packetIdentifier, MqttClientPublishReasonCode reasonCode, string reasonString, IReadOnlyCollection<MqttUserProperty> userProperties)
{
PacketIdentifier = packetIdentifier;
ReasonCode = reasonCode;
ReasonString = reasonString;
UserProperties = userProperties;
}
/// <summary>
/// Returns if the overall status of the publish is a success. This can be the reason code _Success_ or
/// _NoMatchingSubscribers_. _NoMatchingSubscribers_ usually indicates only that no other client is interested in the topic but overall transmit
/// _NoMatchingSubscribers_. _NoMatchingSubscribers_ usually indicates only that no other client is interested in the
/// topic but overall transmit
/// to the server etc. was a success.
/// </summary>
public bool IsSuccess => ReasonCode == MqttClientPublishReasonCode.Success || ReasonCode == MqttClientPublishReasonCode.NoMatchingSubscribers;
......@@ -19,19 +28,19 @@ namespace MQTTnet.Client
/// <summary>
/// Gets the packet identifier which was used for this publish.
/// </summary>
public ushort? PacketIdentifier { get; set; }
public ushort? PacketIdentifier { get; }
/// <summary>
/// Gets or sets the reason code.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public MqttClientPublishReasonCode ReasonCode { get; set; } = MqttClientPublishReasonCode.Success;
public MqttClientPublishReasonCode ReasonCode { get; } = MqttClientPublishReasonCode.Success;
/// <summary>
/// Gets or sets the reason string.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public string ReasonString { get; set; }
public string ReasonString { get; }
/// <summary>
/// Gets or sets the user properties.
......@@ -40,8 +49,8 @@ namespace MQTTnet.Client
/// As long as you don’t exceed the maximum message size, you can use an unlimited number of user properties to add
/// metadata to MQTT messages and pass information between publisher, broker, and subscriber.
/// The feature is very similar to the HTTP header concept.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public IReadOnlyCollection<MqttUserProperty> UserProperties { get; internal set; }
public IReadOnlyCollection<MqttUserProperty> UserProperties { get; }
}
}
\ No newline at end of file
......@@ -10,25 +10,23 @@ namespace MQTTnet.Client
{
public sealed class MqttClientPublishResultFactory
{
static readonly MqttClientPublishResult EmptySuccessResult = new MqttClientPublishResult();
static readonly IReadOnlyCollection<MqttUserProperty> EmptyUserProperties = new List<MqttUserProperty>();
static readonly MqttClientPublishResult AtMostOnceSuccessResult = new MqttClientPublishResult(null, MqttClientPublishReasonCode.Success, null, EmptyUserProperties);
public MqttClientPublishResult Create(MqttPubAckPacket pubAckPacket)
{
// QoS 0 has no response. So we treat it as a success always.
if (pubAckPacket == null)
{
return EmptySuccessResult;
return AtMostOnceSuccessResult;
}
var result = new MqttClientPublishResult
{
var result = new MqttClientPublishResult(
pubAckPacket.PacketIdentifier,
// Both enums have the same values. So it can be easily converted.
ReasonCode = (MqttClientPublishReasonCode)(int)pubAckPacket.ReasonCode,
PacketIdentifier = pubAckPacket.PacketIdentifier,
ReasonString = pubAckPacket.ReasonString,
UserProperties = pubAckPacket.UserProperties ?? EmptyUserProperties
};
(MqttClientPublishReasonCode)(int)pubAckPacket.ReasonCode,
pubAckPacket.ReasonString,
pubAckPacket.UserProperties ?? EmptyUserProperties);
return result;
}
......@@ -37,43 +35,28 @@ namespace MQTTnet.Client
{
if (pubRecPacket == null || pubCompPacket == null)
{
return new MqttClientPublishResult
{
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError
};
var packetIdentifier = pubRecPacket?.PacketIdentifier ?? pubCompPacket?.PacketIdentifier;
return new MqttClientPublishResult(packetIdentifier, MqttClientPublishReasonCode.ImplementationSpecificError, null, EmptyUserProperties);
}
MqttClientPublishResult result;
// The PUBCOMP is the last packet in QoS 2. So we use the results from that instead of PUBREC.
if (pubCompPacket.ReasonCode == MqttPubCompReasonCode.PacketIdentifierNotFound)
{
result = new MqttClientPublishResult
{
PacketIdentifier = pubCompPacket.PacketIdentifier,
ReasonCode = MqttClientPublishReasonCode.UnspecifiedError,
ReasonString = pubCompPacket.ReasonString,
UserProperties = pubCompPacket.UserProperties ?? EmptyUserProperties
};
return result;
return new MqttClientPublishResult(
pubCompPacket.PacketIdentifier,
MqttClientPublishReasonCode.UnspecifiedError,
pubCompPacket.ReasonString,
pubCompPacket.UserProperties ?? EmptyUserProperties);
}
result = new MqttClientPublishResult
{
PacketIdentifier = pubCompPacket.PacketIdentifier,
ReasonCode = MqttClientPublishReasonCode.Success,
ReasonString = pubCompPacket.ReasonString,
UserProperties = pubCompPacket.UserProperties ?? EmptyUserProperties
};
var reasonCode = MqttClientPublishReasonCode.Success;
if (pubRecPacket.ReasonCode != MqttPubRecReasonCode.Success)
{
// Both enums share the same values.
result.ReasonCode = (MqttClientPublishReasonCode)pubRecPacket.ReasonCode;
reasonCode = (MqttClientPublishReasonCode)pubRecPacket.ReasonCode;
}
return result;
return new MqttClientPublishResult(pubCompPacket.PacketIdentifier, reasonCode, null, pubCompPacket.UserProperties ?? EmptyUserProperties);
}
}
}
\ No newline at end of file
......@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using MQTTnet.Packets;
......@@ -9,23 +10,34 @@ namespace MQTTnet.Client
{
public sealed class MqttClientSubscribeResult
{
public IReadOnlyCollection<MqttClientSubscribeResultItem> Items { get; internal set; }
public MqttClientSubscribeResult(ushort packetIdentifier, IReadOnlyCollection<MqttClientSubscribeResultItem> items, string reasonString, IReadOnlyCollection<MqttUserProperty> userProperties)
{
PacketIdentifier = packetIdentifier;
Items = items ?? throw new ArgumentNullException(nameof(items));
ReasonString = reasonString;
UserProperties = userProperties ?? throw new ArgumentNullException(nameof(userProperties));
}
/// <summary>
/// Gets the result for every topic filter item.
/// </summary>
public IReadOnlyCollection<MqttClientSubscribeResultItem> Items { get; }
/// <summary>
/// Gets the user properties which were part of the SUBACK packet.
/// MQTTv5 only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public IReadOnlyCollection<MqttUserProperty> UserProperties { get; internal set; }
public IReadOnlyCollection<MqttUserProperty> UserProperties { get; }
/// <summary>
/// Gets the reason string.
/// MQTTv5 only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public string ReasonString { get; internal set; }
public string ReasonString { get; }
/// <summary>
/// Gets the packet identifier which was used.
/// </summary>
public ushort PacketIdentifier { get; internal set; }
public ushort PacketIdentifier { get; }
}
}
\ No newline at end of file
......@@ -16,42 +16,35 @@ namespace MQTTnet.Client
public MqttClientSubscribeResult Create(MqttSubscribePacket subscribePacket, MqttSubAckPacket subAckPacket)
{
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
if (subAckPacket == null) throw new ArgumentNullException(nameof(subAckPacket));
if (subscribePacket == null)
{
throw new ArgumentNullException(nameof(subscribePacket));
}
if (subAckPacket == null)
{
throw new ArgumentNullException(nameof(subAckPacket));
}
// MQTTv5.0.0 handling.
if (subAckPacket.ReasonCodes.Any() && subAckPacket.ReasonCodes.Count != subscribePacket.TopicFilters.Count)
{
throw new MqttProtocolViolationException(
"The reason codes are not matching the topic filters [MQTT-3.9.3-1].");
throw new MqttProtocolViolationException("The reason codes are not matching the topic filters [MQTT-3.9.3-1].");
}
var items = new List<MqttClientSubscribeResultItem>();
for (var i = 0; i < subscribePacket.TopicFilters.Count; i++)
{
items.Add(CreateSubscribeResultItem(i, subscribePacket, subAckPacket));
}
var result = new MqttClientSubscribeResult
{
PacketIdentifier = subAckPacket.PacketIdentifier,
ReasonString = subAckPacket.ReasonString,
UserProperties = subAckPacket.UserProperties ?? EmptyUserProperties,
Items = items
};
return result;
return new MqttClientSubscribeResult(subAckPacket.PacketIdentifier, items, subAckPacket.ReasonString, subAckPacket.UserProperties ?? EmptyUserProperties);
}
static MqttClientSubscribeResultItem CreateSubscribeResultItem(int index, MqttSubscribePacket subscribePacket, MqttSubAckPacket subAckPacket)
{
var resultCode = (MqttClientSubscribeResultCode) subAckPacket.ReasonCodes[index];
return new MqttClientSubscribeResultItem
{
TopicFilter = subscribePacket.TopicFilters[index],
ResultCode = resultCode,
};
var resultCode = (MqttClientSubscribeResultCode)subAckPacket.ReasonCodes[index];
return new MqttClientSubscribeResultItem(subscribePacket.TopicFilters[index], resultCode);
}
}
}
\ No newline at end of file
......@@ -2,22 +2,29 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using MQTTnet.Packets;
namespace MQTTnet.Client
{
public sealed class MqttClientSubscribeResultItem
{
public MqttClientSubscribeResultItem(MqttTopicFilter topicFilter, MqttClientSubscribeResultCode resultCode)
{
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
ResultCode = resultCode;
}
/// <summary>
/// Gets or sets the topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public MqttTopicFilter TopicFilter { get; internal set; }
public MqttTopicFilter TopicFilter { get; }
/// <summary>
/// Gets or sets the result code.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public MqttClientSubscribeResultCode ResultCode { get; internal set; }
public MqttClientSubscribeResultCode ResultCode { get; }
}
}
......@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using MQTTnet.Packets;
......@@ -9,23 +10,38 @@ namespace MQTTnet.Client
{
public sealed class MqttClientUnsubscribeResult
{
public IReadOnlyCollection<MqttClientUnsubscribeResultItem> Items { get; internal set; }
public MqttClientUnsubscribeResult(
ushort packetIdentifier,
IReadOnlyCollection<MqttClientUnsubscribeResultItem> items,
string reasonString,
IReadOnlyCollection<MqttUserProperty> userProperties)
{
PacketIdentifier = packetIdentifier;
Items = items ?? throw new ArgumentNullException(nameof(items));
ReasonString = reasonString;
UserProperties = userProperties ?? throw new ArgumentNullException(nameof(userProperties));
}
/// <summary>
/// Gets the user properties which were part of the UNSUBACK packet.
/// MQTTv5 only.
/// Gets the result for every topic filter item.
/// </summary>
public IReadOnlyCollection<MqttUserProperty> UserProperties { get; internal set; }
public IReadOnlyCollection<MqttClientUnsubscribeResultItem> Items { get; }
/// <summary>
/// Gets the reason string.
/// MQTTv5 only.
/// Gets the packet identifier which was used.
/// </summary>
public string ReasonString { get; internal set; }
public ushort PacketIdentifier { get; }
/// <summary>
/// Gets the reason string.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public string ReasonString { get; }
/// <summary>
/// Gets the packet identifier which was used.
/// Gets the user properties which were part of the UNSUBACK packet.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public ushort PacketIdentifier { get; internal set; }
public IReadOnlyCollection<MqttUserProperty> UserProperties { get; }
}
}
}
\ No newline at end of file
......@@ -12,17 +12,23 @@ namespace MQTTnet.Client
public sealed class MqttClientUnsubscribeResultFactory
{
static readonly IReadOnlyCollection<MqttUserProperty> EmptyUserProperties = new List<MqttUserProperty>();
public MqttClientUnsubscribeResult Create(MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
{
if (unsubscribePacket == null) throw new ArgumentNullException(nameof(unsubscribePacket));
if (unsubAckPacket == null) throw new ArgumentNullException(nameof(unsubAckPacket));
if (unsubscribePacket == null)
{
throw new ArgumentNullException(nameof(unsubscribePacket));
}
if (unsubAckPacket == null)
{
throw new ArgumentNullException(nameof(unsubAckPacket));
}
// MQTTv3.1.1 has no reason code at all!
if (unsubAckPacket.ReasonCodes != null && unsubAckPacket.ReasonCodes.Count != unsubscribePacket.TopicFilters.Count)
{
throw new MqttProtocolViolationException(
"The return codes are not matching the topic filters [MQTT-3.9.3-1].");
throw new MqttProtocolViolationException("The return codes are not matching the topic filters [MQTT-3.9.3-1].");
}
var items = new List<MqttClientUnsubscribeResultItem>();
......@@ -30,33 +36,21 @@ namespace MQTTnet.Client
{
items.Add(CreateUnsubscribeResultItem(i, unsubscribePacket, unsubAckPacket));
}
var result = new MqttClientUnsubscribeResult
{
PacketIdentifier = unsubAckPacket.PacketIdentifier,
ReasonString = unsubAckPacket.ReasonString,
UserProperties = unsubAckPacket.UserProperties ?? EmptyUserProperties,
Items = items
};
return result;
return new MqttClientUnsubscribeResult(unsubscribePacket.PacketIdentifier, items, unsubAckPacket.ReasonString, unsubAckPacket.UserProperties ?? EmptyUserProperties);
}
static MqttClientUnsubscribeResultItem CreateUnsubscribeResultItem(int index, MqttUnsubscribePacket unsubscribePacket, MqttUnsubAckPacket unsubAckPacket)
{
var resultCode = MqttClientUnsubscribeResultCode.Success;
if (unsubAckPacket.ReasonCodes != null)
{
// MQTTv3.1.1 has no reason code and no return code!.
resultCode = (MqttClientUnsubscribeResultCode) unsubAckPacket.ReasonCodes[index];
resultCode = (MqttClientUnsubscribeResultCode)unsubAckPacket.ReasonCodes[index];
}
return new MqttClientUnsubscribeResultItem
{
TopicFilter = unsubscribePacket.TopicFilters[index],
ResultCode = resultCode
};
return new MqttClientUnsubscribeResultItem(unsubscribePacket.TopicFilters[index], resultCode);
}
}
}
\ No newline at end of file
......@@ -2,20 +2,28 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace MQTTnet.Client
{
public sealed class MqttClientUnsubscribeResultItem
{
public MqttClientUnsubscribeResultItem(string topicFilter, MqttClientUnsubscribeResultCode resultCode)
{
TopicFilter = topicFilter ?? throw new ArgumentNullException(nameof(topicFilter));
ResultCode = resultCode;
}
/// <summary>
/// Gets or sets the topic filter.
/// The topic filter can contain topics and wildcards.
/// Gets or sets the result code.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public string TopicFilter { get; internal set; }
public MqttClientUnsubscribeResultCode ResultCode { get; }
/// <summary>
/// Gets or sets the result code.
/// Hint: MQTT 5 feature only.
/// Gets or sets the topic filter.
/// The topic filter can contain topics and wildcards.
/// </summary>
public MqttClientUnsubscribeResultCode ResultCode { get; internal set; }
public string TopicFilter { get; }
}
}
\ No newline at end of file
......@@ -8,8 +8,14 @@ namespace MQTTnet.Diagnostics
{
public sealed class InspectMqttPacketEventArgs : EventArgs
{
public MqttPacketFlowDirection Direction { get; internal set; }
public InspectMqttPacketEventArgs(MqttPacketFlowDirection direction, byte[] buffer)
{
Direction = direction;
Buffer = buffer ?? throw new ArgumentNullException(nameof(buffer));
}
public byte[] Buffer { get; set; }
public byte[] Buffer { get; }
public MqttPacketFlowDirection Direction { get; }
}
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ namespace MQTTnet.Server
{
public sealed class PreparingSessionEventArgs : EventArgs
{
public string Id { get; internal set; }
public string Id { get; set; }
// TODO: Allow adding of packets to the queue etc.
......
......@@ -9,7 +9,6 @@ using System.Security.Cryptography.X509Certificates;
using System.Text;
using MQTTnet.Adapter;
using MQTTnet.Formatter;
using MQTTnet.Implementations;
using MQTTnet.Internal;
using MQTTnet.Packets;
using MQTTnet.Protocol;
......@@ -20,10 +19,11 @@ namespace MQTTnet.Server
{
readonly MqttConnectPacket _connectPacket;
public ValidatingConnectionEventArgs(MqttConnectPacket connectPacket, IMqttChannelAdapter clientAdapter)
public ValidatingConnectionEventArgs(MqttConnectPacket connectPacket, IMqttChannelAdapter clientAdapter, IDictionary sessionItems)
{
_connectPacket = connectPacket ?? throw new ArgumentNullException(nameof(connectPacket));
ChannelAdapter = clientAdapter ?? throw new ArgumentNullException(nameof(clientAdapter));
SessionItems = sessionItems ?? throw new ArgumentNullException(nameof(sessionItems));
}
/// <summary>
......@@ -34,13 +34,13 @@ namespace MQTTnet.Server
/// <summary>
/// Gets or sets the authentication data.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public byte[] AuthenticationData => _connectPacket.AuthenticationData;
/// <summary>
/// Gets or sets the authentication method.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public string AuthenticationMethod => _connectPacket.AuthenticationMethod;
......@@ -99,7 +99,7 @@ namespace MQTTnet.Server
/// Gets or sets the reason code. When a MQTTv3 client connects the enum value must be one which is
/// also supported in MQTTv3. Otherwise the connection attempt will fail because not all codes can be
/// converted properly.
/// MQTTv5 only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public MqttConnectReasonCode ReasonCode { get; set; } = MqttConnectReasonCode.Success;
......@@ -114,19 +114,19 @@ namespace MQTTnet.Server
/// <summary>
/// Gets the request problem information.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public bool RequestProblemInformation => _connectPacket.RequestProblemInformation;
/// <summary>
/// Gets the request response information.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public bool RequestResponseInformation => _connectPacket.RequestResponseInformation;
/// <summary>
/// Gets or sets the response authentication data.
/// MQTTv5 only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public byte[] ResponseAuthenticationData { get; set; }
......@@ -137,14 +137,14 @@ namespace MQTTnet.Server
/// As long as you don’t exceed the maximum message size, you can use an unlimited number of user properties to add
/// metadata to MQTT messages and pass information between publisher, broker, and subscriber.
/// The feature is very similar to the HTTP header concept.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> ResponseUserProperties { get; set; }
/// <summary>
/// Gets or sets the server reference. This can be used together with i.e. "Server Moved" to send
/// a different server address to the client.
/// MQTTv5 only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public string ServerReference { get; set; }
......@@ -158,7 +158,7 @@ namespace MQTTnet.Server
/// <summary>
/// Gets or sets a key/value collection that can be used to share data within the scope of this session.
/// </summary>
public IDictionary SessionItems { get; internal set; }
public IDictionary SessionItems { get; }
/// <summary>
/// Gets or sets the topic alias maximum.
......@@ -169,7 +169,7 @@ namespace MQTTnet.Server
[Obsolete("This property name has a typo. Use 'UserName' instead. This one will be removed soon.")]
public string Username => _connectPacket.Username;
public string UserName => _connectPacket.Username;
/// <summary>
......@@ -179,7 +179,7 @@ namespace MQTTnet.Server
/// As long as you don’t exceed the maximum message size, you can use an unlimited number of user properties to add
/// metadata to MQTT messages and pass information between publisher, broker, and subscriber.
/// The feature is very similar to the HTTP header concept.
/// Hint: MQTT 5 feature only.
/// <remarks>MQTT 5.0.0+ feature.</remarks>
/// </summary>
public List<MqttUserProperty> UserProperties => _connectPacket.UserProperties;
......
......@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
namespace MQTTnet.Server
{
......@@ -13,8 +14,15 @@ namespace MQTTnet.Server
ApplicationMessage = applicationMessage ?? throw new ArgumentNullException(nameof(applicationMessage));
}
public string SenderClientId { get; set; } = string.Empty;
public MqttApplicationMessage ApplicationMessage { get; }
/// <summary>
/// Gets or sets the session items which should be used for all event handlers which are involved in message
/// processing.
/// If _null_ is specified the singleton session items from the server are used instead.
/// </summary>
public IDictionary CustomSessionItems { get; set; }
public MqttApplicationMessage ApplicationMessage { get; set; }
public string SenderClientId { get; set; } = string.Empty;
}
}
\ No newline at end of file
......@@ -669,11 +669,9 @@ namespace MQTTnet.Server
async Task<ValidatingConnectionEventArgs> ValidateConnection(MqttConnectPacket connectPacket, IMqttChannelAdapter channelAdapter)
{
var eventArgs = new ValidatingConnectionEventArgs(connectPacket, channelAdapter)
{
SessionItems = new ConcurrentDictionary<object, object>()
};
// TODO: Load session items from persisted sessions in the future.
var sessionItems = new ConcurrentDictionary<object, object>();
var eventArgs = new ValidatingConnectionEventArgs(connectPacket, channelAdapter, sessionItems);
await _eventContainer.ValidatingConnectionEvent.InvokeAsync(eventArgs).ConfigureAwait(false);
// Check the client ID and set a random one if supported.
......
......@@ -232,9 +232,11 @@ namespace MQTTnet.Server
throw new NotSupportedException("Injected application messages must contain a topic. Topic alias is not supported.");
}
var sessionItems = injectedApplicationMessage.CustomSessionItems ?? ServerSessionItems;
return _clientSessionsManager.DispatchApplicationMessage(
injectedApplicationMessage.SenderClientId,
ServerSessionItems,
sessionItems,
injectedApplicationMessage.ApplicationMessage,
cancellationToken);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册