TcpOutboundGateway:无法关联响应 - 没有缓存的待处理回复
TcpOutboundGateway : Cannot correlate response - no pending reply for Cached
我使用 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.
我该如何解决这个问题?我的配置 class:
@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();
}
}
你的解串器看起来很可疑; 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 {
或者,如我所说,使用默认反序列化器。
我使用 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.
我该如何解决这个问题?我的配置 class:
@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();
}
}
你的解串器看起来很可疑; 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 {
或者,如我所说,使用默认反序列化器。