|
10 | 10 | using MQTTnet.Internal; |
11 | 11 | using MQTTnet.Packets; |
12 | 12 | using MQTTnet.Protocol; |
| 13 | +using static MQTTnet.Server.MqttClientSubscriptionsManager; |
13 | 14 |
|
14 | 15 | namespace MQTTnet.Server |
15 | 16 | { |
@@ -177,6 +178,13 @@ public async Task<SubscribeResult> Subscribe(MqttSubscribePacket subscribePacket |
177 | 178 |
|
178 | 179 | var addedSubscriptions = new List<string>(); |
179 | 180 | var finalTopicFilters = new List<MqttTopicFilter>(); |
| 181 | + var atLeastOnceSubscriptionResults = new List<CreateSubscriptionResult>(); |
| 182 | + |
| 183 | + IList<MqttApplicationMessage> retainedApplicationMessages = null; |
| 184 | + if (subscribePacket.TopicFilters.Any(f => f.QualityOfServiceLevel != MqttQualityOfServiceLevel.AtLeastOnce)) |
| 185 | + { |
| 186 | + retainedApplicationMessages = await _retainedMessagesManager.GetMessages().ConfigureAwait(false); |
| 187 | + } |
180 | 188 |
|
181 | 189 | // The topic filters are order by its QoS so that the higher QoS will win over a |
182 | 190 | // lower one. |
@@ -208,6 +216,24 @@ public async Task<SubscribeResult> Subscribe(MqttSubscribePacket subscribePacket |
208 | 216 | finalTopicFilters.Add(topicFilter); |
209 | 217 |
|
210 | 218 | FilterRetainedApplicationMessages(retainedApplicationMessages, createSubscriptionResult, result); |
| 219 | + if (createSubscriptionResult.Subscription.GrantedQualityOfServiceLevel != MqttQualityOfServiceLevel.AtLeastOnce) |
| 220 | + { |
| 221 | + FilterRetainedApplicationMessages(retainedApplicationMessages, createSubscriptionResult, result); |
| 222 | + } |
| 223 | + else |
| 224 | + { |
| 225 | + atLeastOnceSubscriptionResults.Add(createSubscriptionResult); |
| 226 | + } |
| 227 | + } |
| 228 | + |
| 229 | + if (atLeastOnceSubscriptionResults.Count != 0) |
| 230 | + { |
| 231 | + // In order to satisfy at least once, we must query for retained messages after creating the subscription. |
| 232 | + retainedApplicationMessages = await _retainedMessagesManager.GetMessages().ConfigureAwait(false); |
| 233 | + foreach (var createSubscriptionResult in atLeastOnceSubscriptionResults) |
| 234 | + { |
| 235 | + FilterRetainedApplicationMessages(retainedApplicationMessages, createSubscriptionResult, result); |
| 236 | + } |
211 | 237 | } |
212 | 238 |
|
213 | 239 | // This call will add the new subscription to the internal storage. |
|
0 commit comments