802 client isnt being notified if message is not delivered (#1568)

This commit is contained in:
Christian
2022-11-09 21:14:53 +01:00
committed by GitHub
parent 56f0a2c31c
commit bfec9dc5ad
10 changed files with 146 additions and 49 deletions
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MQTTnet.Server
{
public sealed class DispatchApplicationMessageResult
{
public DispatchApplicationMessageResult(int matchingSubscribersCount)
{
MatchingSubscribersCount = matchingSubscribersCount;
}
public int MatchingSubscribersCount { get; }
}
}
+4 -3
View File
@@ -237,9 +237,10 @@ namespace MQTTnet.Server
return;
}
DispatchApplicationMessageResult dispatchResult = null;
if (processPublish && applicationMessage != null)
{
await _sessionsManager.DispatchApplicationMessage(Id, applicationMessage).ConfigureAwait(false);
dispatchResult = await _sessionsManager.DispatchApplicationMessage(Id, applicationMessage).ConfigureAwait(false);
}
switch (publishPacket.QualityOfServiceLevel)
@@ -251,13 +252,13 @@ namespace MQTTnet.Server
}
case MqttQualityOfServiceLevel.AtLeastOnce:
{
var pubAckPacket = _packetFactories.PubAck.Create(publishPacket, interceptingPublishEventArgs);
var pubAckPacket = _packetFactories.PubAck.Create(publishPacket, interceptingPublishEventArgs, dispatchResult);
Session.EnqueueControlPacket(new MqttPacketBusItem(pubAckPacket));
break;
}
case MqttQualityOfServiceLevel.ExactlyOnce:
{
var pubRecPacket = _packetFactories.PubRec.Create(publishPacket, interceptingPublishEventArgs);
var pubRecPacket = _packetFactories.PubRec.Create(publishPacket, interceptingPublishEventArgs, dispatchResult);
Session.EnqueueControlPacket(new MqttPacketBusItem(pubRecPacket));
break;
}
@@ -127,21 +127,20 @@ namespace MQTTnet.Server
_logger.Verbose("Session for client '{0}' deleted.", clientId);
}
public async Task DispatchApplicationMessage(string senderId, MqttApplicationMessage applicationMessage)
public async Task<DispatchApplicationMessageResult> DispatchApplicationMessage(string senderId, MqttApplicationMessage applicationMessage)
{
var matchingSubscribersCount = 0;
try
{
if (applicationMessage.Retain)
{
await _retainedMessagesManager.UpdateMessage(senderId, applicationMessage).ConfigureAwait(false);
}
var deliveryCount = 0;
List<MqttSession> subscriberSessions;
lock (_sessionsManagementLock)
{
// only subscriber clients are of interest here.
subscriberSessions = _subscriberSessions.ToList();
}
@@ -187,17 +186,22 @@ namespace MQTTnet.Server
}
session.EnqueueDataPacket(new MqttPacketBusItem(newPublishPacket));
deliveryCount++;
matchingSubscribersCount++;
_logger.Verbose("Client '{0}': Queued PUBLISH packet with topic '{1}'.", session.Id, applicationMessage.Topic);
}
await FireApplicationMessageNotConsumedEvent(applicationMessage, deliveryCount, senderId);
if (matchingSubscribersCount == 0)
{
await FireApplicationMessageNotConsumedEvent(applicationMessage, senderId).ConfigureAwait(false);
}
}
catch (Exception exception)
{
_logger.Error(exception, "Unhandled exception while processing next queued application message.");
}
return new DispatchApplicationMessageResult(matchingSubscribersCount);
}
public void Dispose()
@@ -575,13 +579,8 @@ namespace MQTTnet.Server
return new MqttSession(clientId, isPersistent, sessionItems, _options, _eventContainer, _retainedMessagesManager, this);
}
async Task FireApplicationMessageNotConsumedEvent(MqttApplicationMessage applicationMessage, int deliveryCount, string senderId)
async Task FireApplicationMessageNotConsumedEvent(MqttApplicationMessage applicationMessage, string senderId)
{
if (deliveryCount > 0)
{
return;
}
if (!_eventContainer.ApplicationMessageNotConsumedEvent.HasHandlers)
{
return;