membersound
membersound

Reputation: 86757

How to return an error message on socket timeout with Spring-Integration

I'm using Spring (Integration) to offer a socket tcp connection. I'm having a specific timeout for this socket.

When the timeout is exceeded, I not only like to shut down the connection (which already works), but also return custom error message (or not closing the connection, but just return the error message). Is that possible?

@Bean
public TcpConnectionFactoryFactoryBean tcpFactory(Converter converter) {
    TcpConnectionFactoryFactoryBean factory = new TcpConnectionFactoryFactoryBean();
    factory.setType("server");
    factory.setPort("8080");
    factory.setSingleUse(true);
    factory.setSoTimeout(10000); //10s; how to return error message?
    return factory;
}

Update:

@Bean
public ApplicationListener<TcpConnectionEvent> tcpErrorListener() {
    TcpConnectionEventListeningMessageProducer producer = new TcpConnectionEventListeningMessageProducer();
    producer.setEventTypes(new Class[] {TcpConnectionCloseEvent.class});
    producer.setOutputChannel(tcpErrorChannel()); //what to do here?
    return producer;
}

Upvotes: 1

Views: 1079

Answers (2)

Gary Russell
Gary Russell

Reputation: 174564

The requirement is a little unusual - what will the client do when it gets the custom error message?

There is currently no easy way to intercept the timeout; you could do it, but you'd have to subclass the connection factory and the connection objects it creates, and override the handleReadException() method.

It would likely be much easier to just handle the sockets directly in your own component and send messages to your flow using a Messaging Gateway. Or, simply make your component a subclass of MessagingGatewaySupport.

Alternatively you could use something in your downstream flow (and don't set a timeout). When a message is received, schedule a task to send the error message in 10 seconds. When the next message arrives, cancel the scheduled task and schedule a new one.

Upvotes: 1

Artem Bilan
Artem Bilan

Reputation: 121282

Actually any closed connection emits TcpConnectionCloseEvent and you can get deal with it using:

<int-event:inbound-channel-adapter channel="connectionClosedChannel" 
      event-types="org.springframework.integration.ip.tcp.connection.TcpConnectionCloseEvent"/>

Having that you not only close connection, but can do any desired logic with that event-flow.

UPDATE

To use it from JavaConfig:

@Bean
public SmartApplicationListener tcpErrorListener() {
    ApplicationEventListeningMessageProducer producer = new ApplicationEventListeningMessageProducer();
    producer.setEventTypes(TcpConnectionCloseEvent.class);
    producer.setOutputChannel(tcpErrorChannel());
    return producer;
}

@Bean
public MessageChannel tcpErrorChannel() {
    return new DirectChannel();
}

Upvotes: 1

Related Questions