mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-15 00:15:15 +08:00
Add new multi threaded application message handler for server.
This commit is contained in:
@@ -4,6 +4,8 @@ namespace MQTTnet.Server
|
||||
{
|
||||
public struct CheckSubscriptionsResult
|
||||
{
|
||||
public static CheckSubscriptionsResult NotSubscribed = new CheckSubscriptionsResult();
|
||||
|
||||
public bool IsSubscribed { get; set; }
|
||||
|
||||
public MqttQualityOfServiceLevel QualityOfServiceLevel { get; set; }
|
||||
|
||||
@@ -1,16 +1,23 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MQTTnet.Diagnostics;
|
||||
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
public class MqttApplicationMessageInterceptorContext
|
||||
public sealed class MqttApplicationMessageInterceptorContext
|
||||
{
|
||||
public MqttApplicationMessageInterceptorContext(string clientId, IDictionary<object, object> sessionItems, MqttApplicationMessage applicationMessage)
|
||||
public MqttApplicationMessageInterceptorContext(string clientId, IDictionary<object, object> sessionItems, IMqttNetScopedLogger logger)
|
||||
{
|
||||
ClientId = clientId;
|
||||
ApplicationMessage = applicationMessage;
|
||||
SessionItems = sessionItems;
|
||||
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently used logger.
|
||||
/// </summary>
|
||||
public IMqttNetScopedLogger Logger { get; }
|
||||
|
||||
public string ClientId { get; }
|
||||
|
||||
public MqttApplicationMessage ApplicationMessage { get; set; }
|
||||
|
||||
@@ -322,19 +322,21 @@ namespace MQTTnet.Server
|
||||
}
|
||||
|
||||
var deliveryCount = 0;
|
||||
|
||||
List<MqttClientSession> sessions;
|
||||
lock (_sessions)
|
||||
{
|
||||
foreach (var clientSession in _sessions.Values)
|
||||
sessions = _sessions.Values.ToList();
|
||||
}
|
||||
|
||||
foreach (var clientSession in sessions)
|
||||
{
|
||||
var isSubscribed = clientSession.EnqueueApplicationMessage(applicationMessage, senderClientId, false);
|
||||
if (isSubscribed)
|
||||
{
|
||||
var isSubscribed = clientSession.EnqueueApplicationMessage(applicationMessage, senderClientId, false);
|
||||
if (isSubscribed)
|
||||
{
|
||||
deliveryCount++;
|
||||
}
|
||||
deliveryCount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (deliveryCount == 0)
|
||||
{
|
||||
var undeliveredMessageInterceptor = _options.UndeliveredMessageInterceptor;
|
||||
@@ -445,7 +447,13 @@ namespace MQTTnet.Server
|
||||
sessionItems = clientConnection.Session.Items;
|
||||
}
|
||||
|
||||
var interceptorContext = new MqttApplicationMessageInterceptorContext(senderClientId, sessionItems, applicationMessage);
|
||||
var interceptorContext = new MqttApplicationMessageInterceptorContext(senderClientId, sessionItems, _logger)
|
||||
{
|
||||
AcceptPublish = true,
|
||||
ApplicationMessage = applicationMessage,
|
||||
CloseConnection = false
|
||||
};
|
||||
|
||||
await interceptor.InterceptApplicationMessagePublishAsync(interceptorContext).ConfigureAwait(false);
|
||||
return interceptorContext;
|
||||
}
|
||||
|
||||
@@ -193,10 +193,7 @@ namespace MQTTnet.Server
|
||||
|
||||
if (qosLevels.Count == 0)
|
||||
{
|
||||
return new CheckSubscriptionsResult
|
||||
{
|
||||
IsSubscribed = false
|
||||
};
|
||||
return CheckSubscriptionsResult.NotSubscribed;
|
||||
}
|
||||
|
||||
return CreateSubscriptionResult(qosLevel, qosLevels);
|
||||
|
||||
@@ -3,9 +3,9 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
public class MqttServerApplicationMessageInterceptorDelegate : IMqttServerApplicationMessageInterceptor
|
||||
public sealed class MqttServerApplicationMessageInterceptorDelegate : IMqttServerApplicationMessageInterceptor
|
||||
{
|
||||
private readonly Func<MqttApplicationMessageInterceptorContext, Task> _callback;
|
||||
readonly Func<MqttApplicationMessageInterceptorContext, Task> _callback;
|
||||
|
||||
public MqttServerApplicationMessageInterceptorDelegate(Action<MqttApplicationMessageInterceptorContext> callback)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MQTTnet.Diagnostics;
|
||||
using MQTTnet.Implementations;
|
||||
using MQTTnet.Internal;
|
||||
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
public sealed class MqttServerMultiThreadedApplicationMessageInterceptorDelegate : IMqttServerApplicationMessageInterceptor
|
||||
{
|
||||
readonly Func<MqttApplicationMessageInterceptorContext, Task> _callback;
|
||||
|
||||
public MqttServerMultiThreadedApplicationMessageInterceptorDelegate(Action<MqttApplicationMessageInterceptorContext> callback)
|
||||
{
|
||||
if (callback == null) throw new ArgumentNullException(nameof(callback));
|
||||
|
||||
_callback = context =>
|
||||
{
|
||||
callback(context);
|
||||
return Task.FromResult(0);
|
||||
};
|
||||
}
|
||||
|
||||
public MqttServerMultiThreadedApplicationMessageInterceptorDelegate(Func<MqttApplicationMessageInterceptorContext, Task> callback)
|
||||
{
|
||||
_callback = callback ?? throw new ArgumentNullException(nameof(callback));
|
||||
}
|
||||
|
||||
public Task InterceptApplicationMessagePublishAsync(MqttApplicationMessageInterceptorContext context)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await _callback.Invoke(context).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
context.Logger.Error(exception, "Error while intercepting application message.");
|
||||
}
|
||||
}).RunInBackground();
|
||||
|
||||
return PlatformAbstractionLayer.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,13 @@ using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Security.Authentication;
|
||||
using MQTTnet.Certificates;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
#if !WINDOWS_UWP
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
#endif
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
namespace MQTTnet.Server
|
||||
{
|
||||
public class MqttServerOptionsBuilder
|
||||
@@ -187,6 +189,24 @@ namespace MQTTnet.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithApplicationMessageInterceptor(Func<MqttApplicationMessageInterceptorContext, Task> value)
|
||||
{
|
||||
_options.ApplicationMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithMultiThreadedApplicationMessageInterceptor(Action<MqttApplicationMessageInterceptorContext> value)
|
||||
{
|
||||
_options.ApplicationMessageInterceptor = new MqttServerMultiThreadedApplicationMessageInterceptorDelegate(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithMultiThreadedApplicationMessageInterceptor(Func<MqttApplicationMessageInterceptorContext, Task> value)
|
||||
{
|
||||
_options.ApplicationMessageInterceptor = new MqttServerMultiThreadedApplicationMessageInterceptorDelegate(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithClientMessageQueueInterceptor(IMqttServerClientMessageQueueInterceptor value)
|
||||
{
|
||||
_options.ClientMessageQueueInterceptor = value;
|
||||
@@ -217,6 +237,12 @@ namespace MQTTnet.Server
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithUndeliveredMessageInterceptor(Action<MqttApplicationMessageInterceptorContext> value)
|
||||
{
|
||||
_options.UndeliveredMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithDefaultEndpointReuseAddress()
|
||||
{
|
||||
_options.DefaultEndpointOptions.ReuseAddress = true;
|
||||
@@ -248,11 +274,5 @@ namespace MQTTnet.Server
|
||||
{
|
||||
return _options;
|
||||
}
|
||||
|
||||
public MqttServerOptionsBuilder WithUndeliveredMessageInterceptor(Action<MqttApplicationMessageInterceptorContext> value)
|
||||
{
|
||||
_options.UndeliveredMessageInterceptor = new MqttServerApplicationMessageInterceptorDelegate(value);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user