Как вернуть сообщение об ошибке по истечении времени ожидания сокета с помощью Spring-Integration

1

Я использую Spring (Integration) чтобы предложить соединение tcp сокета. У меня есть определенный тайм-аут для этого сокета.

Когда тайм-аут превышен, я не только хочу отключить соединение (которое уже работает), но и вернуть сообщение об ошибке (или не закрыть соединение, а просто вернуть сообщение об ошибке). Это возможно?

@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;
}

Обновить:

@Bean
public ApplicationListener<TcpConnectionEvent> tcpErrorListener() {
    TcpConnectionEventListeningMessageProducer producer = new TcpConnectionEventListeningMessageProducer();
    producer.setEventTypes(new Class[] {TcpConnectionCloseEvent.class});
    producer.setOutputChannel(tcpErrorChannel()); //what to do here?
    return producer;
}
  • 0
    Не могли бы вы показать StackTrace, когда soTimeout исчерпан? Я постараюсь найти код оттуда, куда можно втиснуть
  • 0
    На самом деле я не получаю стека трассировки по таймауту (по крайней мере, на стороне сервера. У меня нет на стороне клиента).
Показать ещё 2 комментария
Теги:
spring
spring-integration
sockets

2 ответа

1
Лучший ответ

Фактически любое закрытое соединение испускает TcpConnectionCloseEvent и вы можете получить с ним дело, используя:

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

Имея это, вы не только закрываете соединение, но можете делать любую желаемую логику с этим event-flow.

ОБНОВИТЬ

Чтобы использовать его из 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();
}
  • 0
    Это выглядит многообещающе. Поддерживается ли уже аннотация int-event ?
  • 0
    Добавлен пример JavaConfig
Показать ещё 12 комментариев
1

Требование немного необычное - что сделает клиент, когда он получит сообщение об ошибке?

В настоящее время нет простого способа перехватить таймаут; вы можете это сделать, но вам придется подклассифицировать фабрику соединений и handleReadException() объекты подключения и переопределить метод handleReadException().

Скорее всего, было бы намного проще обрабатывать сокеты непосредственно в вашем собственном компоненте и отправлять сообщения в поток через Messaging Gateway. Или просто сделайте свой компонент подклассом MessagingGatewaySupport.

В качестве альтернативы вы можете использовать что-то в своем потоке вниз (и не устанавливать тайм-аут). Когда сообщение получено, планируйте задачу для отправки сообщения об ошибке за 10 секунд. Когда придет следующее сообщение, отмените запланированное задание и назначьте новый.

  • 0
    Клиент просто отобразит пользовательское сообщение об ошибке, и пользователь клиента отреагирует соответствующим образом. Устаревший инструмент не будет правильно обрабатывать тайм-аут соединения и вызывать непредсказуемые ошибки. Таким образом, я должен предотвратить закрытие соединения. Так что, возможно, индивидуальный планировщик - единственный шанс здесь ...

Ещё вопросы

Сообщество Overcoder
Наверх
Меню