Fix subscribe interceptor

This commit is contained in:
Christian Kratky
2017-10-28 13:19:04 +02:00
parent 019ef1398e
commit 30df7d4c9e
5 changed files with 51 additions and 34 deletions
@@ -30,6 +30,7 @@ namespace MQTTnet.Implementations
if (options.DefaultEndpointOptions.IsEnabled) if (options.DefaultEndpointOptions.IsEnabled)
{ {
_defaultEndpointSocket = new StreamSocketListener(); _defaultEndpointSocket = new StreamSocketListener();
_defaultEndpointSocket.Control.NoDelay = true;
await _defaultEndpointSocket.BindServiceNameAsync(options.GetDefaultEndpointPort().ToString(), SocketProtectionLevel.PlainSocket); await _defaultEndpointSocket.BindServiceNameAsync(options.GetDefaultEndpointPort().ToString(), SocketProtectionLevel.PlainSocket);
_defaultEndpointSocket.ConnectionReceived += AcceptDefaultEndpointConnectionsAsync; _defaultEndpointSocket.ConnectionReceived += AcceptDefaultEndpointConnectionsAsync;
} }
@@ -57,6 +58,8 @@ namespace MQTTnet.Implementations
{ {
try try
{ {
args.Socket.Control.NoDelay = true;
var clientAdapter = _mqttCommunicationAdapterFactory.CreateServerMqttCommunicationAdapter(new MqttTcpChannel(args.Socket)); var clientAdapter = _mqttCommunicationAdapterFactory.CreateServerMqttCommunicationAdapter(new MqttTcpChannel(args.Socket));
ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter)); ClientAccepted?.Invoke(this, new MqttServerAdapterClientAcceptedEventArgs(clientAdapter));
} }
+41 -27
View File
@@ -142,51 +142,65 @@ namespace MQTTnet.Core.Server
} }
} }
private async Task ProcessReceivedPacketAsync(IMqttCommunicationAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken) private Task ProcessReceivedPacketAsync(IMqttCommunicationAdapter adapter, MqttBasePacket packet, CancellationToken cancellationToken)
{ {
if (packet is MqttSubscribePacket subscribePacket) if (packet is MqttPingReqPacket)
{ {
var subscribeResult = _subscriptionsManager.Subscribe(subscribePacket); return adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttPingRespPacket());
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, subscribeResult.ResponsePacket); }
EnqueueRetainedMessages(subscribePacket);
if (subscribeResult.CloseConnection) if (packet is MqttPublishPacket publishPacket)
{
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttDisconnectPacket());
Stop();
}
}
else if (packet is MqttUnsubscribePacket unsubscribePacket)
{ {
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, _subscriptionsManager.Unsubscribe(unsubscribePacket)); return HandleIncomingPublishPacketAsync(adapter, publishPacket, cancellationToken);
} }
else if (packet is MqttPublishPacket publishPacket)
if (packet is MqttPubRelPacket pubRelPacket)
{ {
await HandleIncomingPublishPacketAsync(adapter, publishPacket, cancellationToken); return HandleIncomingPubRelPacketAsync(adapter, pubRelPacket, cancellationToken);
} }
else if (packet is MqttPubRelPacket pubRelPacket)
if (packet is MqttPubRecPacket pubRecPacket)
{ {
await HandleIncomingPubRelPacketAsync(adapter, pubRelPacket, cancellationToken); return adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, pubRecPacket.CreateResponse<MqttPubRelPacket>());
} }
else if (packet is MqttPubRecPacket pubRecPacket)
{ if (packet is MqttPubAckPacket || packet is MqttPubCompPacket)
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, pubRecPacket.CreateResponse<MqttPubRelPacket>());
}
else if (packet is MqttPubAckPacket || packet is MqttPubCompPacket)
{ {
// Discard message. // Discard message.
return Task.FromResult(0);
} }
else if (packet is MqttPingReqPacket)
if (packet is MqttSubscribePacket subscribePacket)
{ {
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttPingRespPacket()); return HandleIncomingSubscribePacketAsync(adapter, subscribePacket, cancellationToken);
} }
else if (packet is MqttDisconnectPacket || packet is MqttConnectPacket)
if (packet is MqttUnsubscribePacket unsubscribePacket)
{
return adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, _subscriptionsManager.Unsubscribe(unsubscribePacket));
}
if (packet is MqttDisconnectPacket || packet is MqttConnectPacket)
{ {
Stop(); Stop();
return Task.FromResult(0);
} }
else
_logger.LogWarning("Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
Stop();
return Task.FromResult(0);
}
private async Task HandleIncomingSubscribePacketAsync(IMqttCommunicationAdapter adapter, MqttSubscribePacket subscribePacket, CancellationToken cancellationToken)
{
var subscribeResult = _subscriptionsManager.Subscribe(subscribePacket, ClientId);
await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, subscribeResult.ResponsePacket);
EnqueueRetainedMessages(subscribePacket);
if (subscribeResult.CloseConnection)
{ {
_logger.LogWarning("Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet); await adapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttDisconnectPacket());
Stop(); Stop();
} }
} }
@@ -39,12 +39,12 @@ namespace MQTTnet.Core.Server
public MqttClientRetainedMessagesManager RetainedMessagesManager { get; } public MqttClientRetainedMessagesManager RetainedMessagesManager { get; }
public async Task RunClientSessionAsync(IMqttCommunicationAdapter clientAdapter) public async Task RunClientSessionAsync(IMqttCommunicationAdapter clientAdapter, CancellationToken cancellationToken)
{ {
var clientId = string.Empty; var clientId = string.Empty;
try try
{ {
if (!(await clientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false) is MqttConnectPacket connectPacket)) if (!(await clientAdapter.ReceivePacketAsync(_options.DefaultCommunicationTimeout, cancellationToken).ConfigureAwait(false) is MqttConnectPacket connectPacket))
{ {
throw new MqttProtocolViolationException("The first packet from a client must be a 'CONNECT' packet [MQTT-3.1.0-1]."); throw new MqttProtocolViolationException("The first packet from a client must be a 'CONNECT' packet [MQTT-3.1.0-1].");
} }
@@ -57,7 +57,7 @@ namespace MQTTnet.Core.Server
var connectReturnCode = ValidateConnection(connectPacket); var connectReturnCode = ValidateConnection(connectPacket);
if (connectReturnCode != MqttConnectReturnCode.ConnectionAccepted) if (connectReturnCode != MqttConnectReturnCode.ConnectionAccepted)
{ {
await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttConnAckPacket
{ {
ConnectReturnCode = connectReturnCode ConnectReturnCode = connectReturnCode
}).ConfigureAwait(false); }).ConfigureAwait(false);
@@ -67,7 +67,7 @@ namespace MQTTnet.Core.Server
var clientSession = GetOrCreateClientSession(connectPacket); var clientSession = GetOrCreateClientSession(connectPacket);
await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, CancellationToken.None, new MqttConnAckPacket await clientAdapter.SendPacketsAsync(_options.DefaultCommunicationTimeout, cancellationToken, new MqttConnAckPacket
{ {
ConnectReturnCode = connectReturnCode, ConnectReturnCode = connectReturnCode,
IsSessionPresent = clientSession.IsExistingSession IsSessionPresent = clientSession.IsExistingSession
@@ -16,7 +16,7 @@ namespace MQTTnet.Core.Server
_options = options?.Value ?? throw new ArgumentNullException(nameof(options)); _options = options?.Value ?? throw new ArgumentNullException(nameof(options));
} }
public MqttClientSubscribeResult Subscribe(MqttSubscribePacket subscribePacket) public MqttClientSubscribeResult Subscribe(MqttSubscribePacket subscribePacket, string clientId)
{ {
if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket)); if (subscribePacket == null) throw new ArgumentNullException(nameof(subscribePacket));
@@ -27,7 +27,7 @@ namespace MQTTnet.Core.Server
{ {
foreach (var topicFilter in subscribePacket.TopicFilters) foreach (var topicFilter in subscribePacket.TopicFilters)
{ {
var interceptorContext = new MqttSubscriptionInterceptorContext("", topicFilter); var interceptorContext = new MqttSubscriptionInterceptorContext(clientId, topicFilter);
_options.SubscriptionsInterceptor?.Invoke(interceptorContext); _options.SubscriptionsInterceptor?.Invoke(interceptorContext);
responsePacket.SubscribeReturnCodes.Add(interceptorContext.AcceptSubscription ? MqttSubscribeReturnCode.SuccessMaximumQoS1 : MqttSubscribeReturnCode.Failure); responsePacket.SubscribeReturnCodes.Add(interceptorContext.AcceptSubscription ? MqttSubscribeReturnCode.SuccessMaximumQoS1 : MqttSubscribeReturnCode.Failure);
+1 -1
View File
@@ -109,7 +109,7 @@ namespace MQTTnet.Core.Server
private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs) private void OnClientAccepted(object sender, MqttServerAdapterClientAcceptedEventArgs eventArgs)
{ {
eventArgs.SessionTask = Task.Run(async () => await _clientSessionsManager.RunClientSessionAsync(eventArgs.Client), _cancellationTokenSource.Token); eventArgs.SessionTask = Task.Run(async () => await _clientSessionsManager.RunClientSessionAsync(eventArgs.Client, _cancellationTokenSource.Token), _cancellationTokenSource.Token);
} }
private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs) private void OnClientConnected(object sender, MqttClientConnectedEventArgs eventArgs)