diff --git a/Mtconnect.TcpAdapter/TcpAdapter.cs b/Mtconnect.TcpAdapter/TcpAdapter.cs index 98a16b6..8dc440f 100644 --- a/Mtconnect.TcpAdapter/TcpAdapter.cs +++ b/Mtconnect.TcpAdapter/TcpAdapter.cs @@ -267,7 +267,7 @@ private async Task ListenForClients() if (!_clients.ContainsKey(client.ClientId)) { - _logger?.LogInformation("New client connection '{ClientId}'", client.ClientId); + _logger?.LogInformation("New client connection '{ClientId}' ({ActiveConnections}/{MaxConnections})", client.ClientId, _clients.Count, MaxConnections); if (_clients.TryAdd(client.ClientId, client)) { client.OnDisconnected += Client_OnConnectionDisconnected; @@ -320,7 +320,7 @@ private void Client_OnConnectionDisconnected(TcpConnection connection, Exception { if (!_clients.ContainsKey(connection.ClientId)) { - _logger?.LogWarning("Client '{ClientId}' is not tracked", connection.ClientId); + _logger?.LogWarning("Client '{ClientId}' could not be disconnected because it is not currently tracked", connection.ClientId); return; } @@ -328,17 +328,21 @@ private void Client_OnConnectionDisconnected(TcpConnection connection, Exception { if (ex == null) { - _logger?.LogInformation("Client disconnected '{ClientId}'", connection.ClientId); + _logger?.LogDebug("Client disconnecting '{ClientId}'", connection.ClientId); } else { - _logger?.LogError("Client '{ClientId}' disconnected due to error: \r\n\t{Error}", connection.ClientId, ex); + _logger?.LogError("Client '{ClientId}' disconnecting due to error: \r\n\t{Error}", connection.ClientId, ex); } if (_clients.TryRemove(connection.ClientId, out TcpConnection client)) { + _logger?.LogInformation("Client '{ClientId}' disconnected", connection.ClientId); if (_clients.Count == 0) { _logger?.LogInformation("No clients connected"); } + } else + { + _logger?.LogWarning("Client '{ClientId}' failed to disconnect and may still linger", connection.ClientId); } } } diff --git a/Mtconnect.TcpAdapter/TcpAdapter.csproj b/Mtconnect.TcpAdapter/TcpAdapter.csproj index 853241e..9c6a2ed 100644 --- a/Mtconnect.TcpAdapter/TcpAdapter.csproj +++ b/Mtconnect.TcpAdapter/TcpAdapter.csproj @@ -19,7 +19,7 @@ git Mtconnect;Adapter;TCP;TAMS; Updated to latest AdapterSDK. Support for reference Agent SHDR commands. - 2.0.3 + 2.0.4 True snupkg true @@ -52,7 +52,7 @@ - + diff --git a/Mtconnect.TcpAdapter/TcpConnection.cs b/Mtconnect.TcpAdapter/TcpConnection.cs index 393aa82..f3b9df6 100644 --- a/Mtconnect.TcpAdapter/TcpConnection.cs +++ b/Mtconnect.TcpAdapter/TcpConnection.cs @@ -4,6 +4,7 @@ using System.Net.Sockets; using System.Security.Policy; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace Mtconnect @@ -14,6 +15,7 @@ namespace Mtconnect public class TcpConnection : IDisposable { private bool _disposing { get; set; } = false; + private bool _disconnecting { get; set; } = false; /// /// An event that fires when the underlying client stream is opened and connected. @@ -53,6 +55,7 @@ public class TcpConnection : IDisposable private TcpClient _client { get; set; } private Task _receiverThread; + private CancellationTokenSource _receiverSource; /// /// Reference to the underlying client stream. Note, only available between and calls. @@ -82,9 +85,10 @@ public void Connect() _stream = _client.GetStream(); + _receiverSource = new CancellationTokenSource(); _receiverThread = Task.Factory.StartNew( receive, - default, + _receiverSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default ); @@ -97,15 +101,40 @@ public void Connect() /// public void Disconnect(Exception ex = null) { + _disconnecting = true; if (_stream == null) return; - _receiverThread?.Dispose(); + try + { + _receiverSource?.Cancel(); + _receiverSource?.Dispose(); + _receiverSource = null; + } + catch (Exception cancellationException) + { + } + + try + { + _receiverThread?.Dispose(); + _receiverThread = null; + } + catch (Exception receiverException) + { + } - _stream?.Close(); - _stream?.Dispose(); - _stream = null; + try + { + _stream?.Close(); + _stream?.Dispose(); + _stream = null; + } + catch (Exception streamException) + { + } if (!_disposing && OnDisconnected != null) OnDisconnected(this, ex); + _disconnecting = false; } /// @@ -150,7 +179,7 @@ private async Task receive() ArrayList readList = new ArrayList(); - while (_client.Connected) + while (_client.Connected && !_disconnecting) { if (!_stream.DataAvailable) { @@ -205,8 +234,8 @@ private async Task receive() public void Dispose() { _disposing = true; - _client?.Dispose(); Disconnect(); + _client?.Dispose(); _disposing = false; } }