Spring Integration ByteArrayRawSerializer TCP客户端服务器

时间:2019-12-04 00:54:58

标签: spring spring-integration

我正在尝试创建一个TCP / IP模拟器,该模拟器模仿无法测试的生产服务器。服务器接收和发送字节数组,而不是字符串。

在使用Spring Integration时,我可以进行不使用ByteArrayRawSerializer的对话,但是当我实现ByteArrayRawSerializer时,即使它们正在被接收,我也无法接收回消息。在服务器上处理。

Transformers.objectToString()方法似乎令人怀疑,但目前我相信我已经尝试了大多数方法。请告知...

重要的客户代码如下:

    @Bean
    FailoverClientConnectionFactory failoverClientFactory() {
        FailoverClientConnectionFactory failoverClientConnectionFactory = new FailoverClientConnectionFactory(underlyingCF());
        failoverClientConnectionFactory.isSingleUse();
        return failoverClientConnectionFactory;
    }

    @Bean
    public List<AbstractClientConnectionFactory> underlyingCF() {

        List<AbstractClientConnectionFactory> connections = new ArrayList<AbstractClientConnectionFactory>();
        TcpNioClientConnectionFactory primary = new TcpNioClientConnectionFactory(primaryTcpServerHost, primaryTcpServerPort);
        primary.isSingleUse();
        primary.setSerializer(new ByteArrayRawSerializer());  // Works when not present
        primary.setDeserializer(new ByteArrayRawSerializer()); // Works when not present
        log.info("Starting with Primary Server/Port as: {}:{}", primaryTcpServerHost, primaryTcpServerPort);

        TcpNioClientConnectionFactory failover = new TcpNioClientConnectionFactory(secondaryTcpServerHost, secondaryTcpServerPort);
        failover.isSingleUse();
        failover.setSerializer(new ByteArrayRawSerializer());  // Works when not present
        failover.setDeserializer(new ByteArrayRawSerializer());  // Works when not present
        log.info("Starting with Secondary Server/Port as: {}:{}", secondaryTcpServerHost, secondaryTcpServerPort);

        connections.add(primary);
        connections.add(failover);

        return connections;
    }

    @Bean
    @DependsOn("failoverClientFactory")
    public IntegrationFlow liveMumClient() {
        return IntegrationFlows.from(Gate.class)
                .handle(Tcp.outboundGateway(failoverClientFactory()))
                .transform(Transformers.objectToString())
                .get();
    }

    public interface Gate {
        // TODO: Use properties for 20000 seems to be unsupported 
        @Gateway(replyTimeout = 20000)
        String sendAndReceive(byte[] out);
    }

服务器配置为:

@Configuration
public class LiveMumTcpConfig {

    @Value("${tcp.server.port}")
    private Integer tcpServerPort;

    @Bean
    public IntegrationFlow server() {
        return IntegrationFlows.from(
                Tcp.inboundGateway(Tcp.netServer(tcpServerPort)
                        .deserializer(new ByteArrayRawSerializer()) // Works when not present
                        .serializer(new ByteArrayRawSerializer()) // Works when not present
                        ))
                .transform(new MessageTransformer())
                .log()
                .handle((p, h) -> {
                    Object retVal;
                    try {
                        retVal = LiveMumTcpHandler.handle(p);
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                    return retVal;
                })
                .get();
    }
}

然后...我得到以下输出:

客户端


2019-12-03 17:31:03.284  INFO 30587 --- [   scheduling-1] gov.nyc.mumweb.service.MumWebService     : Sending Generated XML <?xml version='1.0' encoding='UTF-8'?><STARFIRECAD sequenceNumber="20191203/17310327410"><polling><date>20191203</date><time>17:31:03</time></polling></STARFIRECAD>
2019-12-03 17:31:03.336  WARN 30587 --- [   scheduling-1] o.s.i.i.tcp.connection.TcpNioConnection  : No publisher available to publish TcpConnectionOpenEvent [source=TcpNioConnection:unknown:0:-1:acec6b6d-0b74-49e1-87ca-f3344cb4cc08], [factory=unknown, connectionId=unknown:0:-1:acec6b6d-0b74-49e1-87ca-f3344cb4cc08] **OPENED**
2019-12-03 17:31:13.340  WARN 30587 --- [   scheduling-1] o.s.i.i.tcp.connection.TcpNioConnection  : No publisher available to publish TcpConnectionCloseEvent [source=TcpNioConnection:unknown:0:-1:acec6b6d-0b74-49e1-87ca-f3344cb4cc08], [factory=unknown, connectionId=unknown:0:-1:acec6b6d-0b74-49e1-87ca-f3344cb4cc08] **CLOSED**
2019-12-03 17:31:13.341 ERROR 30587 --- [   scheduling-1] o.s.i.ip.tcp.TcpOutboundGateway          : Tcp Gateway exception

java.lang.RuntimeException: org.springframework.integration.MessageTimeoutException: Timed out waiting for response, failedMessage=GenericMessage [payload=byte[166], headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2394a155, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@2394a155, id=f58e889b-786b-37e3-6c0b-0abf88337e0c, timestamp=1575422199215}]
    at gov.nyc.mumweb.service.MumWebService.heartbeat(MumWebService.java:44) ~[classes/:na]
    at gov.nyc.mumweb.config.LiveMumHeartbeatConfig$Runner.run(LiveMumHeartbeatConfig.java:36) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_141]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_141]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_141]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_141]
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_141]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_141]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_141]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_141]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_141]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_141]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_141]
Caused by: org.springframework.integration.MessageTimeoutException: Timed out waiting for response
    at org.springframework.integration.ip.tcp.TcpOutboundGateway.getReply(TcpOutboundGateway.java:216) ~[spring-integration-ip-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.ip.tcp.TcpOutboundGateway.handleRequestMessage(TcpOutboundGateway.java:161) ~[spring-integration-ip-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:127) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:170) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:115) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:73) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:453) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:403) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187) ~[spring-messaging-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:233) ~[spring-messaging-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.messaging.core.GenericMessagingTemplate.doSendAndReceive(GenericMessagingTemplate.java:47) ~[spring-messaging-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.messaging.core.AbstractMessagingTemplate.sendAndReceive(AbstractMessagingTemplate.java:46) ~[spring-messaging-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:97) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.core.MessagingTemplate.sendAndReceive(MessagingTemplate.java:38) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.messaging.core.AbstractMessagingTemplate.convertSendAndReceive(AbstractMessagingTemplate.java:96) ~[spring-messaging-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.messaging.core.AbstractMessagingTemplate.convertSendAndReceive(AbstractMessagingTemplate.java:86) ~[spring-messaging-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.gateway.MessagingGatewaySupport.doSendAndReceive(MessagingGatewaySupport.java:495) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.gateway.MessagingGatewaySupport.sendAndReceive(MessagingGatewaySupport.java:469) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.gateway.GatewayProxyFactoryBean.sendOrSendAndReceive(GatewayProxyFactoryBean.java:564) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:489) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.gateway.GatewayProxyFactoryBean.doInvoke(GatewayProxyFactoryBean.java:464) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:453) ~[spring-integration-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.1.RELEASE.jar:5.2.1.RELEASE]
    at com.sun.proxy.$Proxy100.sendAndReceive(Unknown Source) ~[na:na]
    at gov.nyc.mumweb.service.MumWebService.heartbeat(MumWebService.java:39) ~[classes/:na]
    ... 14 common frames omitted

服务器端:

GenericMessage [payload=<?xml version='1.0' encoding='UTF-8'?>< ... >, headers={replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3e5610e3, errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@3e5610e3, ip_tcp_remotePort=51898, ip_connectionId=localhost:51898:8077:e2c7776b-3f60-45b5-8433-031f094bbefe, ip_localInetAddress=/127.0.0.1, ip_address=127.0.0.1, id=4dca4f70-5c12-0be4-96bb-26188cc90f71, ip_hostname=localhost, timestamp=1575419803630}]

1 个答案:

答案 0 :(得分:2)

TCP是一个流-您需要一些信息来告诉接收方该流中什么构成“消息”。原始反序列化器使用套接字关闭符来分隔消息。

您不能在服务器端通过网关使用原始反序列化器,因为客户端关闭套接字意味着我们无法发送答复。

只要设置了singleUseConnections属性,您就可以在服务器端使用原始的序列化程序进行答复,以便网关在发送答复时关闭连接,因此客户端将获得EOF

既然您同时控制客户端和服务器端,为什么要使用原始(反)序列化器?

相关问题