scenario is we need to configure the maxClient and if it is reached we have to close the connection if it is greater than maxClient. For this we are adding connectionId in List and if list is greater than max client then we close the TcpNioConnection. but while we close it throws below Exception.
java.nio.channels.ClosedChannelException: null at java.base/java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSelectableChannel.java:222) at org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory.createConnectionForAcceptedChannel(TcpNioServerConnectionFactory.java:260) at org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory.doAccept(TcpNioServerConnectionFactory.java:229) at org.springframework.integration.ip.tcp.connection.AbstractConnectionFactory.keyAcceptable(AbstractConnectionFactory.java:776) at org.springframework.integration.ip.tcp.connection.AbstractConnectionFactory.handleKey(AbstractConnectionFactory.java:725) at org.springframework.integration.ip.tcp.connection.AbstractConnectionFactory.processNioSelections(AbstractConnectionFactory.java:672) at org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory.doSelect(TcpNioServerConnectionFactory.java:194) at org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory.run(TcpNioServerConnectionFactory.java:155) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:833)
Below is the code
private final Logger log = LoggerFactory.getLogger(TcpConnectionApplicationListener.class);
List<String> connectionIdList = new ArrayList<String>();
@Override
public void onApplicationEvent(TcpConnectionEvent event) {
String connectionId = event.getConnectionId();
String ipAddressPort = null;
if(Objects.nonNull(connectionId)) {
ipAddressPort = connectionId.substring(0,connectionId.lastIndexOf(":"));
ipAddressPort = ipAddressPort.substring(0, ipAddressPort.lastIndexOf(":"));
}
log.info("ipAddressPort >>> "+ipAddressPort);
if (event.getSource() instanceof TcpNioConnection) {
log.info("inside connection factory >>> ");
TcpNioConnection nioConnection = (TcpNioConnection) event.getSource();
if(connectionIdList.size() > 1) {
nioConnection.close();
log.info("isClosed >>> "+ nioConnection.getSocketInfo().isClosed());
return;
}
}
if (event instanceof TcpConnectionOpenEvent) {
connectionIdList.add(event.getConnectionId());
log.info("TcpConnectionOpenEvent connection id = {}",connectionIdList.size());
log.info("TCP Open connection event with id={}", event.getConnectionId());
} else if (event instanceof TcpConnectionCloseEvent) {
connectionIdList.remove(event.getConnectionId());
log.info("TcpConnectionCloseEvent connection id = {}",connectionIdList.size());
log.info("TCP Close connection event with id={}", event.getConnectionId());
}
}
Below is the code for Integration Flow
IntegrationFlows.from(Tcp.inboundGateway(Tcp.nioServer(port)
.soReceiveBufferSize(512)
.deserializer(new MessageDeserializer())
.serializer(new MessageSerializer())
))
.log()
.transform(Transformers.objectToString())
.handle("outboundService", "processAndSendMessage")
.get();
}
can you please let me know how to resolve this issue or is there any other way that we can configure max clients in Tcp.nioServer so that many connections only Exists.
Instead of closing connection I suggest to thrown an exception. This way the logic in the
TcpNioServerConnectionFactorywill be like this:You also can do that from a custom
TcpNioConnectionSupportinstead of an event listener.