mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-21 20:33:05 +08:00
fixed deadlock and object disposed exception
This commit is contained in:
@@ -126,18 +126,11 @@ namespace MQTTnet.Server
|
|||||||
_logger.Error(exception, "Client '{0}': Unhandled exception while receiving client packets.", ClientId);
|
_logger.Error(exception, "Client '{0}': Unhandled exception while receiving client packets.", ClientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stop(MqttClientDisconnectType.NotClean);
|
Stop(MqttClientDisconnectType.NotClean, true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (_adapter != null)
|
await Cleanup().ConfigureAwait(false);
|
||||||
{
|
|
||||||
_adapter.ReadingPacketStarted -= OnAdapterReadingPacketStarted;
|
|
||||||
_adapter.ReadingPacketCompleted -= OnAdapterReadingPacketCompleted;
|
|
||||||
await Cleanup().ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
_adapter = null;
|
|
||||||
|
|
||||||
_cleanupHandle?.Dispose();
|
_cleanupHandle?.Dispose();
|
||||||
_cleanupHandle = null;
|
_cleanupHandle = null;
|
||||||
@@ -153,8 +146,18 @@ namespace MQTTnet.Server
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _adapter.DisconnectAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
|
var adapter = _adapter;
|
||||||
_adapter.Dispose();
|
if (adapter == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_adapter = null;
|
||||||
|
|
||||||
|
adapter.ReadingPacketStarted -= OnAdapterReadingPacketStarted;
|
||||||
|
adapter.ReadingPacketCompleted -= OnAdapterReadingPacketCompleted;
|
||||||
|
await adapter.DisconnectAsync(_options.DefaultCommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
adapter.Dispose();
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
@@ -163,6 +166,11 @@ namespace MQTTnet.Server
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Stop(MqttClientDisconnectType type)
|
public void Stop(MqttClientDisconnectType type)
|
||||||
|
{
|
||||||
|
Stop(type, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Stop(MqttClientDisconnectType type, bool isInsideSession)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -183,7 +191,10 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
_willMessage = null;
|
_willMessage = null;
|
||||||
|
|
||||||
_workerTask?.GetAwaiter().GetResult();
|
if (!isInsideSession)
|
||||||
|
{
|
||||||
|
_workerTask?.GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@@ -329,18 +340,18 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
if (packet is MqttDisconnectPacket)
|
if (packet is MqttDisconnectPacket)
|
||||||
{
|
{
|
||||||
Stop(MqttClientDisconnectType.Clean);
|
Stop(MqttClientDisconnectType.Clean, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet is MqttConnectPacket)
|
if (packet is MqttConnectPacket)
|
||||||
{
|
{
|
||||||
Stop(MqttClientDisconnectType.NotClean);
|
Stop(MqttClientDisconnectType.NotClean, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_logger.Warning(null, "Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
|
_logger.Warning(null, "Client '{0}': Received not supported packet ({1}). Closing connection.", ClientId, packet);
|
||||||
Stop(MqttClientDisconnectType.NotClean);
|
Stop(MqttClientDisconnectType.NotClean, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnqueueSubscribedRetainedMessages(ICollection<TopicFilter> topicFilters)
|
private void EnqueueSubscribedRetainedMessages(ICollection<TopicFilter> topicFilters)
|
||||||
@@ -359,7 +370,7 @@ namespace MQTTnet.Server
|
|||||||
|
|
||||||
if (subscribeResult.CloseConnection)
|
if (subscribeResult.CloseConnection)
|
||||||
{
|
{
|
||||||
Stop(MqttClientDisconnectType.NotClean);
|
Stop(MqttClientDisconnectType.NotClean, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,6 +262,46 @@ namespace MQTTnet.Core.Tests
|
|||||||
Assert.AreEqual(1, disconnectCalled);
|
Assert.AreEqual(1, disconnectCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public async Task MqttServer_HandleCleanDisconnect()
|
||||||
|
{
|
||||||
|
MqttNetGlobalLogger.LogMessagePublished += (_, e) =>
|
||||||
|
{
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[{e.TraceMessage.Timestamp:s}] {e.TraceMessage.Source} {e.TraceMessage.Message}");
|
||||||
|
};
|
||||||
|
|
||||||
|
var serverAdapter = new MqttTcpServerAdapter(new MqttNetLogger().CreateChildLogger());
|
||||||
|
var s = new MqttFactory().CreateMqttServer(new[] { serverAdapter }, new MqttNetLogger());
|
||||||
|
|
||||||
|
var clientConnectedCalled = 0;
|
||||||
|
var clientDisconnectedCalled = 0;
|
||||||
|
|
||||||
|
s.ClientConnected += (_, __) => clientConnectedCalled++;
|
||||||
|
s.ClientDisconnected += (_, __) => clientDisconnectedCalled++;
|
||||||
|
|
||||||
|
var clientOptions = new MqttClientOptionsBuilder()
|
||||||
|
.WithTcpServer("localhost")
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
await s.StartAsync(new MqttServerOptions());
|
||||||
|
|
||||||
|
var c1 = new MqttFactory().CreateMqttClient();
|
||||||
|
|
||||||
|
await c1.ConnectAsync(clientOptions);
|
||||||
|
|
||||||
|
await Task.Delay(100);
|
||||||
|
|
||||||
|
await c1.DisconnectAsync();
|
||||||
|
|
||||||
|
await Task.Delay(100);
|
||||||
|
|
||||||
|
await s.StopAsync();
|
||||||
|
|
||||||
|
await Task.Delay(100);
|
||||||
|
|
||||||
|
Assert.AreEqual(clientConnectedCalled, clientDisconnectedCalled);
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public async Task MqttServer_RetainedMessagesFlow()
|
public async Task MqttServer_RetainedMessagesFlow()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user