繁体   English   中英

Spring 集成 ByteArrayRawSerializer TCP 客户端服务器

[英]Spring Integration ByteArrayRawSerializer TCP Client Server

我正在尝试创建一个 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}]

TCP 是一个流 - 您需要一些东西来告诉接收者在该流中什么构成了“消息”。 原始解串器使用套接字关闭来分隔消息。

您不能在带有网关的服务器端使用原始解串器,因为客户端关闭套接字意味着我们无法发送回复。

您可以在服务器端使用原始序列化程序进行回复,只要设置了singleUseConnections属性,网关就会在发送回复时关闭连接,这样客户端就会获得 EOF。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM