Skip to content

Commit

Permalink
Improve reconnect handling with self-manged TcpClient instance
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusWichelmann committed Jan 27, 2024
1 parent 8f67b86 commit ea6c83b
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions src/EnergyExporter/Modbus/ModbusReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class ModbusReader
private readonly string _host;
private readonly ushort _port;

private TcpClient? _tcpClient;

private readonly ModbusTcpClient _modbusClient = new();
private readonly SemaphoreSlim _modbusLock = new(1);

Expand All @@ -34,7 +36,7 @@ public async Task<TDevice> ReadDeviceAsync<TDevice>(byte unit, ushort startRegis
try
{
// Ensure the client is connected
if (!_modbusClient.IsConnected)
if (_tcpClient?.Connected != true)
await ReconnectAsync();

_logger.LogDebug(
Expand Down Expand Up @@ -101,7 +103,8 @@ public async Task<TDevice> ReadDeviceAsync<TDevice>(byte unit, ushort startRegis
catch
{
// Make sure the connection gets reestablished after a failed read, just in case...
_modbusClient.Disconnect();
_tcpClient?.Close();
_tcpClient = null;
throw;
}

Expand All @@ -117,11 +120,14 @@ private async Task ReconnectAsync()
{
_logger.LogInformation("Connecting to modbus server at {Host}.", _host);

var tcpClient = new TcpClient();
await tcpClient.ConnectAsync(_host, _port);
// Close previous TCP client.
_tcpClient?.Close();

_tcpClient = new TcpClient();
await _tcpClient.ConnectAsync(_host, _port);

_modbusClient.ReadTimeout = 5000;
_modbusClient.Initialize(tcpClient, ModbusEndianness.LittleEndian);
_modbusClient.Initialize(_tcpClient, ModbusEndianness.LittleEndian);

_logger.LogInformation("Modbus connection to {Host} established.", _host);
}
Expand Down

0 comments on commit ea6c83b

Please sign in to comment.