baraldi-l-proxaut opened a new issue, #1781:
URL: https://github.com/apache/plc4x/issues/1781
I wrote a Camel route that reads signals from a Phoenix I/O via modbus
protocol every 500 milliseconds.
The I/o Phoenix is connected to my laptop via ethernet cable.
Initially the connection was opened and closed for each read instruction,
but subsequently I moved to a managed pool of connections to reuse the same
connection.
In this way I managed to reduce reading times and avoided saturating the PLC
connections.
Before, opening and closing the connection, took me a total of 1 (max 2)
seconds to read each reading.
With a managed pool of already open connections, I can read within the
expected 500 ms.
The problem I'm facing now is that if the ethernet cable is disconnected, an
Exception is thrown that I can't catch and subsequently the connection to that
IP is no longer usable until the route is restarted.
Do you have any idea on how to catch the java.net.SocketException Connection
reset?
This is the java.net.SocketException thrown:
`2024-09-23T18:18:44.111+02:00 WARN 29312 --- [ntLoopGroup-3-1]
i.netty.channel.DefaultChannelPipeline : An exceptionCaught() event was
fired, and it reached at the tail of the pipeline. It usually means the last
handler in the pipeline did not handle the exception.
java.net.SocketException: Connection reset
at
java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:394)
~[na:na]
at
java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:426) ~[na:na]
at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:254)
~[netty-buffer-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132)
~[netty-buffer-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:357)
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
~[netty-transport-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at
io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
~[netty-common-4.1.97.Final.jar:4.1.97.Final]
at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
`
This is the Camel route:
```java
fromF("timer:%s?period=%d", tagGroupName, interval)
.routeId(tagGroupName)
.process(exchange -> {
Map<String, Object> result =
tagReaderService.directRead(tagGroupTriggerData.getHost(),
tagGroupTriggerData.getPort(),
DevicePlugin.MODBUS,
tagGroupTriggerData.getTagList());
exchange.getIn().setBody(result);
})
.marshal().json(JsonLibrary.Jackson)
.process(exchange -> {
String body = exchange.getIn().getBody(String.class);
tagReaderService.put(tagGroupName, body);
});
```
This the tagReaderService.directRead method:
```java
public Map<String, Object> directRead(final String host, final Integer
port, final DevicePlugin devicePlugin,
final List<TagTriggerData> tags)
throws PlcConnectionException, ExecutionException, InterruptedException {
if (devicePlugin == DevicePlugin.OMRON_FINS_UDP) {
Map<String, Object> result = new HashMap<>(tags.size());
for (var tagDTO : tags) {
OmronReadRequest request = new OmronReadRequest();
request.setAddress(tagDTO.getAddress());
OmronReadResponse response =
producerTemplate.requestBody("direct:read-omron-single", request,
OmronReadResponse.class);
result.put(tagDTO.getName(), response.getResponse());
}
return result;
} else {
return plcPoolConnectionService.readValues(host, port,
devicePlugin, tags);
}
}
```
This is the plcPoolConnectionService.readValues invoked:
```java
public Map<String, Object> readValues(final String host, final Integer
port, final DevicePlugin devicePlugin, final List<TagTriggerData> tags) throws
PlcConnectionException, ExecutionException, InterruptedException {
ConnectionWrapper connection = getConnectionWrapper(host, port,
devicePlugin);
return connection.readValues(tags);
}
```
This is the getConnectionWrapper:
```java
private ConnectionWrapper getConnectionWrapper(final String host, final
Integer port, final DevicePlugin devicePlugin) throws PlcConnectionException {
String key = host +
ofNullable(port).map(Object::toString).orElse("");
ConnectionWrapper connection = connections.get(key);
if (connection == null) {
connection = createNewConnection(host, port, devicePlugin);
connections.put(key, connection);
}
return connection;
}
```
And here i create the connection:
```java
private ConnectionWrapper createNewConnection(final String host, final
Integer port, final DevicePlugin devicePlugin) throws PlcConnectionException {
return switch (devicePlugin) {
case S7COMM -> ConnectionWrapper.s7Connection(driverManager,
host);
case MODBUS ->
ConnectionWrapper.modbusTcpConnection(driverManager, host, port);
default -> throw new RuntimeException("Unsupported device
plugin: " + devicePlugin);
};
}
public static ConnectionWrapper modbusTcpConnection(final
PlcDriverManager driverManager, final String host, final Integer port) throws
PlcConnectionException {
String connectionString =
String.format(MODBUS_TCP_CONNECTION_STRING, host);
return new ConnectionWrapper(driverManager, connectionString);
}
private ConnectionWrapper(final PlcDriverManager driverManager, final
String connectionString) throws PlcConnectionException {
connection = driverManager.getConnection(connectionString);
}
```
[TagGroupRouteBuilder.zip](https://github.com/user-attachments/files/17100934/TagGroupRouteBuilder.zip)
Feel free to write to me for any information and if there are any points to
explore further.
Thank you,
Luca
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]