我正在尝试创建一个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
中没有收到任何数据。为确保数据存在,我可以使用telnet成功连接到远程tcp服务器
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'
答案 0 :(得分:0)
将客户端连接工厂与入站端点一起使用时,不会刺激打开连接(客户端工厂通常用于出站操作,并且在发送第一条消息时会建立连接)。
在此模式下使用时,您需要setClientMode(true)
。这将启动一个任务,该任务打开(并监视)出站连接。
通常,入站适配器使用
type="server"
连接工厂,该工厂监听传入的连接请求。在某些情况下,您可能需要反向建立连接,以使入站适配器连接到外部服务器,然后等待该连接上的入站消息。通过在入站适配器上设置
client-mode="true"
支持此拓扑。在这种情况下,连接工厂必须是client类型,并且必须将单次使用设置为false。另外两个属性支持此机制。
retry-interval
指定(以毫秒为单位)框架在连接失败后尝试重新连接的频率。scheduler
提供了一个TaskScheduler来安排连接尝试并测试连接是否仍处于活动状态。
(该框架提供了默认的调度程序)。
对于Bonus问题,您需要在创建应用程序上下文之前找到主机/端口。或在获得信息后动态创建连接工厂和网关。