【问题标题】:TcpOutboundGateway : Cannot correlate response - no pending reply for CachedTcpOutboundGateway : 无法关联响应 - 缓存没有待处理的回复
【发布时间】:2019-01-17 22:13:01
【问题描述】:

我使用 spring 集成连接到 tcp/ip 套接字服务器,我创建了基于 telnet-mock https://github.com/maltempi/telnet-mock 的模拟服务器。我可以发送和接收消息,但是当我关闭模拟服务器时,在主应用程序中会发生循环错误并占用所有 CPU 时间:

ERROR 13942 --- [pool-4-thread-1] o.s.i.ip.tcp.TcpOutboundGateway : Cannot correlate response - no pending reply for Cached:localhost:3002:46550:f6234e17-c486-4506-82c8-a757a08ba73d.

我该如何解决这个问题?我的配置类:

@EnableIntegration
@RequiredArgsConstructor
@Configuration
public class StpClientConfiguration {

private static final String REQUEST_CHANNEL = "toStp";
private static final String OUTPUT_CHANNEL = "resultToMap";
private static final String CRLF = "\\0";

private final ApplicationProperties applicationProperties;
private final ApplicationContext context;

private static String readUntil(InputStream inputStream, String stopWord) throws IOException {
    StringBuilder sb = new StringBuilder();
    BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream));
    int r;
    while ((r = buffer.read()) != -1) {
        char c = (char) r;
        sb.append(c);
        if (sb.toString().endsWith(stopWord)) {
            break;
        }
    }
    return sb.toString();
}

@Bean
public CachingClientConnectionFactory connectionFactory() {
    TcpNetClientConnectionFactory factory = new TcpNetClientConnectionFactory(
            applicationProperties.getHost(), applicationProperties.getPort());

    factory.setApplicationEventPublisher(this.context);
    factory.setTcpSocketSupport(new DefaultTcpSocketSupport());
    factory.setDeserializer((InputStream inputStream) -> readUntil(inputStream, CRLF));

    return new CachingClientConnectionFactory(factory, applicationProperties.getPoolSize());
}

/**
 * Creates the tcp gateway for service activation.
 *
 * @return the message handler
 */
@Bean
@ServiceActivator(inputChannel = REQUEST_CHANNEL)
public MessageHandler outboundGateway() {
    TcpOutboundGateway gateway = new TcpOutboundGateway();
    gateway.setConnectionFactory(connectionFactory());
    gateway.setOutputChannelName(OUTPUT_CHANNEL);

    return gateway;
}

@MessagingGateway(defaultRequestChannel = REQUEST_CHANNEL)
public interface RequestGateway {

    Map<String, String> send(String message);
}

@Bean
@Transformer(inputChannel = OUTPUT_CHANNEL)
public ObjectToMapTransformer objectToMapTransformer() {
    return new ObjectToMapTransformer();
}

}

【问题讨论】:

    标签: spring-boot spring-integration tcpclient tcpsocket


    【解决方案1】:

    您的反序列化器看起来很可疑; telnet 消息以\r\n 结束,而不是\\0

    使用 telnet 的默认解串器(默认为 ByteArrayCrLfSerializer)。

    当反序列化器检测到流的正常结束(-1)时,在消息之间,它必须抛出一个SoftEndOfStreamException 来告诉框架套接字已关闭。您的代码不断返回零长度字符串,

    /**
     * Used to communicate that a stream has closed, but between logical
     * messages.
     */
    public class SoftEndOfStreamException extends IOException {
    

    或者,正如我所说,使用默认的反序列化器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 2019-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-03
      相关资源
      最近更新 更多