Интеграция TCP-клиента Spring с Java Config - PullRequest
0 голосов
/ 23 ноября 2018

Я пытаюсь создать TCP-клиент для подключения к удаленному tcp-серверу и ждать получения сообщений.Пока у меня есть следующий код:

@EnableIntegration
@IntegrationComponentScan
@Configuration
public class TcpClientConfig {

@Bean
public TcpInboundGateway tcpInbound(AbstractClientConnectionFactory connectionFactory) {
    TcpInboundGateway gate = new TcpInboundGateway();
    gate.setConnectionFactory(connectionFactory);
    gate.setClientMode(false);
    gate.setRequestChannel(fromTcp());
    return gate;
}

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

@MessageEndpoint
public static class Echo {

    @Transformer(inputChannel = "fromTcp", outputChannel = "serviceChannel")
    public String convert(byte[] bytes) {
        return new String(bytes);
    }
}

@ServiceActivator(inputChannel = "serviceChannel")
public void messageToService(String in) {
    System.out.println(in);
}

@Bean
public EndOfLineSerializer endOfLineSerializer() {
    return new EndOfLineSerializer();
}

@Bean
public AbstractClientConnectionFactory clientConnectionFactory() {
    TcpNetClientConnectionFactory tcpNetServerConnectionFactory = new TcpNetClientConnectionFactory("192.XXX.XXX.XX", 4321);
    tcpNetServerConnectionFactory.setSingleUse(false);
    tcpNetServerConnectionFactory.setSoTimeout(300000);
   tcpNetServerConnectionFactory.setDeserializer(endOfLineSerializer());
    tcpNetServerConnectionFactory.setSerializer(endOfLineSerializer());
    tcpNetServerConnectionFactory.setMapper(new TimeoutMapper());
    return tcpNetServerConnectionFactory;
}
}

Он запускается и подключается к удаленному серверу.Однако я не получаю никаких данных в моем serviceActivator методе messageToService.Чтобы убедиться, что данные существуют, я могу успешно подключиться к своему удаленному tcp-серверу, используя telnet

telnet 192.XXX.XXX.XX 4321
Trying 192.XXX.XXX.XX...
Connected to 192.XXX.XXX.XX.
Escape character is '^]'.
Hello World

Я подтвердил, что ничто не поразило мой EndOfLineSerializer.Что не так с моим TCP-клиентом?

Бонус : Давайте предположим, что имя хоста и порт определяются путем запроса API.Как я скажу TcpNetClientConnectionFactory ждать, чтобы попытаться подключиться, пока у меня не будут правильные данные для порта?

Отладочный вывод:

main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2018-11-22 23:00:46.182 DEBUG 35953 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Autodetecting user-defined JMX MBeans
2018-11-22 23:00:46.194 DEBUG 35953 --- [           main] .s.i.c.GlobalChannelInterceptorProcessor : No global channel interceptors.
2018-11-22 23:00:46.198 DEBUG 35953 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase -2147483648
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {logging-channel-adapter:_org.springframework.integration.errorLogger} as a subscriber to the 'errorChannel' channel
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.i.channel.PublishSubscribeChannel    : Channel 'application.errorChannel' has 1 subscriber(s).
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started _org.springframework.integration.errorLogger
2018-11-22 23:00:46.198 DEBUG 35953 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean '_org.springframework.integration.errorLogger'
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {service-activator:tcpClientConfig.messageToService.serviceActivator} as a subscriber to the 'serviceChannel' channel
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application.serviceChannel' has 1 subscriber(s).
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started tcpClientConfig.messageToService.serviceActivator
2018-11-22 23:00:46.198 DEBUG 35953 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean 'tcpClientConfig.messageToService.serviceActivator'
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : Adding {transformer:tcpClientConfig.Echo.convert.transformer} as a subscriber to the 'toTcp' channel
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.integration.channel.DirectChannel    : Channel 'application.toTcp' has 1 subscriber(s).
2018-11-22 23:00:46.198  INFO 35953 --- [           main] o.s.i.endpoint.EventDrivenConsumer       : started tcpClientConfig.Echo.convert.transformer
2018-11-22 23:00:46.198 DEBUG 35953 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean 'tcpClientConfig.Echo.convert.transformer'
2018-11-22 23:00:46.198 DEBUG 35953 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 0
2018-11-22 23:00:46.199  INFO 35953 --- [           main] .s.i.i.t.c.TcpNetClientConnectionFactory : started clientConnectionFactory, host=192.XXX.XXX.90, port=4321
2018-11-22 23:00:46.199 DEBUG 35953 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean 'clientConnectionFactory'
2018-11-22 23:00:46.199  INFO 35953 --- [           main] .s.i.i.t.c.TcpNetClientConnectionFactory : started clientConnectionFactory, host=192.XXX.XXX.90, port=4321
2018-11-22 23:00:46.199  INFO 35953 --- [           main] o.s.i.ip.tcp.TcpInboundGateway           : started tcpInbound
2018-11-22 23:00:46.199 DEBUG 35953 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Successfully started bean 'tcpInbound'

1 Ответ

0 голосов
/ 23 ноября 2018

При использовании фабрики клиентских соединений с входящей конечной точкой нет стимула открывать соединение (клиентские фабрики обычно используются для исходящих операций, и соединение устанавливается при отправке первого сообщения).

Когдаиспользуется в этом режиме, вам нужно setClientMode(true).Это запускает задачу, которая открывает (и контролирует) исходящее соединение.

См. документацию

Обычно входящие адаптеры используют фабрику соединений type="server",который прослушивает входящие запросы на соединение.В некоторых случаях может потребоваться установить обратное соединение, чтобы входящий адаптер подключался к внешнему серверу и затем ожидал входящих сообщений по этому соединению.

Эта топология поддерживается установкой client-mode="true" ввходящий адаптер.В этом случае фабрика соединений должна иметь тип client и для одноразового использования должно быть установлено значение false.

Два дополнительных атрибута поддерживают этот механизм.retry-interval указывает (в миллисекундах), как часто платформа пытается восстановить соединение после сбоя соединения.scheduler предоставляет TaskScheduler для планирования попыток подключения и проверки того, что подключение все еще активно.

(В платформе предусмотрен планировщик по умолчанию).

Для вашего дополнительного вопроса:вам нужно будет найти хост / порт перед созданием контекста приложения;или создайте фабрику соединений и шлюз динамически после получения информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...