mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-20 11:45:43 +08:00
Expose retained messages to server interface.
This commit is contained in:
@@ -16,14 +16,18 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
IMqttServerOptions Options { get; }
|
IMqttServerOptions Options { get; }
|
||||||
|
|
||||||
|
[Obsolete("This method is no longer async. Use the not async method.")]
|
||||||
Task<IList<IMqttClientSessionStatus>> GetClientSessionsStatusAsync();
|
Task<IList<IMqttClientSessionStatus>> GetClientSessionsStatusAsync();
|
||||||
|
|
||||||
|
IList<IMqttClientSessionStatus> GetClientSessionsStatus();
|
||||||
|
|
||||||
|
IList<MqttApplicationMessage> GetRetainedMessages();
|
||||||
|
Task ClearRetainedMessagesAsync();
|
||||||
|
|
||||||
Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters);
|
Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters);
|
||||||
Task UnsubscribeAsync(string clientId, IList<string> topicFilters);
|
Task UnsubscribeAsync(string clientId, IList<string> topicFilters);
|
||||||
|
|
||||||
Task StartAsync(IMqttServerOptions options);
|
Task StartAsync(IMqttServerOptions options);
|
||||||
Task StopAsync();
|
Task StopAsync();
|
||||||
|
|
||||||
Task ClearRetainedMessagesAsync();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ namespace MQTTnet.Server
|
|||||||
return Task.Run(() => RunSession(clientAdapter, _cancellationToken), _cancellationToken);
|
return Task.Run(() => RunSession(clientAdapter, _cancellationToken), _cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IList<IMqttClientSessionStatus>> GetClientStatusAsync()
|
public IList<IMqttClientSessionStatus> GetClientStatus()
|
||||||
{
|
{
|
||||||
var result = new List<IMqttClientSessionStatus>();
|
var result = new List<IMqttClientSessionStatus>();
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ namespace MQTTnet.Server
|
|||||||
result.Add(status);
|
result.Add(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.FromResult((IList<IMqttClientSessionStatus>)result);
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EnqueueApplicationMessage(MqttClientSession senderClientSession, MqttPublishPacket publishPacket)
|
public void EnqueueApplicationMessage(MqttClientSession senderClientSession, MqttPublishPacket publishPacket)
|
||||||
|
|||||||
@@ -52,7 +52,51 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await HandleMessageInternalAsync(clientId, applicationMessage).ConfigureAwait(false);
|
List<MqttApplicationMessage> messagesForSave = null;
|
||||||
|
lock (_messages)
|
||||||
|
{
|
||||||
|
var saveIsRequired = false;
|
||||||
|
|
||||||
|
if (applicationMessage.Payload?.Length == 0)
|
||||||
|
{
|
||||||
|
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
||||||
|
_logger.Verbose("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!_messages.TryGetValue(applicationMessage.Topic, out var existingMessage))
|
||||||
|
{
|
||||||
|
_messages[applicationMessage.Topic] = applicationMessage;
|
||||||
|
saveIsRequired = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (existingMessage.QualityOfServiceLevel != applicationMessage.QualityOfServiceLevel || !existingMessage.Payload.SequenceEqual(applicationMessage.Payload ?? new byte[0]))
|
||||||
|
{
|
||||||
|
_messages[applicationMessage.Topic] = applicationMessage;
|
||||||
|
saveIsRequired = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.Verbose("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saveIsRequired)
|
||||||
|
{
|
||||||
|
messagesForSave = new List<MqttApplicationMessage>(_messages.Values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messagesForSave == null)
|
||||||
|
{
|
||||||
|
_logger.Verbose("Skipped saving retained messages because no changes were detected.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_options.Storage != null)
|
||||||
|
{
|
||||||
|
await _options.Storage.SaveRetainedMessagesAsync(messagesForSave).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@@ -84,6 +128,14 @@ namespace MQTTnet.Server
|
|||||||
return retainedMessages;
|
return retainedMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IList<MqttApplicationMessage> GetMessages()
|
||||||
|
{
|
||||||
|
lock (_messages)
|
||||||
|
{
|
||||||
|
return _messages.Values.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task ClearMessagesAsync()
|
public Task ClearMessagesAsync()
|
||||||
{
|
{
|
||||||
lock (_messages)
|
lock (_messages)
|
||||||
@@ -91,55 +143,12 @@ namespace MQTTnet.Server
|
|||||||
_messages.Clear();
|
_messages.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _options.Storage.SaveRetainedMessagesAsync(new List<MqttApplicationMessage>());
|
if (_options.Storage != null)
|
||||||
}
|
|
||||||
|
|
||||||
private async Task HandleMessageInternalAsync(string clientId, MqttApplicationMessage applicationMessage)
|
|
||||||
{
|
|
||||||
var saveIsRequired = false;
|
|
||||||
|
|
||||||
lock (_messages)
|
|
||||||
{
|
{
|
||||||
if (applicationMessage.Payload?.Length == 0)
|
return _options.Storage.SaveRetainedMessagesAsync(new List<MqttApplicationMessage>());
|
||||||
{
|
|
||||||
saveIsRequired = _messages.Remove(applicationMessage.Topic);
|
|
||||||
_logger.Verbose("Client '{0}' cleared retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!_messages.TryGetValue(applicationMessage.Topic, out var existingMessage))
|
|
||||||
{
|
|
||||||
_messages[applicationMessage.Topic] = applicationMessage;
|
|
||||||
saveIsRequired = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (existingMessage.QualityOfServiceLevel != applicationMessage.QualityOfServiceLevel || !existingMessage.Payload.SequenceEqual(applicationMessage.Payload ?? new byte[0]))
|
|
||||||
{
|
|
||||||
_messages[applicationMessage.Topic] = applicationMessage;
|
|
||||||
saveIsRequired = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.Verbose("Client '{0}' set retained message for topic '{1}'.", clientId, applicationMessage.Topic);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!saveIsRequired)
|
return Task.FromResult((object)null);
|
||||||
{
|
|
||||||
_logger.Verbose("Skipped saving retained messages because no changes were detected.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (saveIsRequired && _options.Storage != null)
|
|
||||||
{
|
|
||||||
List<MqttApplicationMessage> messages;
|
|
||||||
lock (_messages)
|
|
||||||
{
|
|
||||||
messages = _messages.Values.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
await _options.Storage.SaveRetainedMessagesAsync(messages).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,17 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
public Task<IList<IMqttClientSessionStatus>> GetClientSessionsStatusAsync()
|
public Task<IList<IMqttClientSessionStatus>> GetClientSessionsStatusAsync()
|
||||||
{
|
{
|
||||||
return _clientSessionsManager.GetClientStatusAsync();
|
return Task.FromResult(_clientSessionsManager.GetClientStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<IMqttClientSessionStatus> GetClientSessionsStatus()
|
||||||
|
{
|
||||||
|
return _clientSessionsManager.GetClientStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<MqttApplicationMessage> GetRetainedMessages()
|
||||||
|
{
|
||||||
|
return _retainedMessagesManager.GetMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters)
|
public Task SubscribeAsync(string clientId, IList<TopicFilter> topicFilters)
|
||||||
|
|||||||
Reference in New Issue
Block a user