我们有一个用Java编写的使用Spring Integration的应用程序。应用程序向3d-party服务发送请求,每个请求都表示为字节数组,并通过纯TCP发送。与3d-party的连接存储在池中(使用CachingClientConnectionFactory)。
我们可以向3d-party发送几种类型的请求,现在需要为每种类型的请求设置不同的超时值。然而,现在这看起来有问题的,只要连接超时设置用于Gateway和ConnectionFactory的部件设置,并且没有办法设置连接超时特定单个请求。
我们希望避免引入多个网关和连接工厂,以支持不同的连接超时。
频道&网关配置
<int:channel id="myInput" />
<int:gateway id="myGateway"
service-interface="com.mypackage.TcpGateway"
default-request-channel="myInput"/>
<int-ip:tcp-outbound-gateway id="myOutGateway"
request-channel="mybInput"
reply-channel="clientBytesChannel"
connection-factory="myConnectionFactory"
request-timeout="${conn.timeout}"
remote-timeout="${conn.timeout}"/>
TcpGateway.java
package com.mypackage.TcpGateway;
public interface TcpGateway {
byte[] send(byte[] message);
}
RequestProcessor.java
public class RequestProcessors {
@Autowired
private TcpGateway myGateway;
public MyResponse process(MyRequest requestMessage) {
byte[] binaryMessage = transformRequest(requestMessage);
byte[] response = myGateway.send(binaryMessage);
return transformResponse(response);
}
// rest of business logic here
}
查看上面的源代码,似乎最简单的方法是扩展本机组件TcpOutboundGateway并将属性remoteTimeout
替换为将超时设置保存为ThreadLocal
变量的单例bean。然后,可以在请求传递到RequestProcessors.process()
之前,根据myGateway.send()
方法中的请求类型设置必要的值。
但是,我无法找到使用我的自定义类重新定义TcpOutboundGateway组件的优雅方法。分析Spring集成的源代码后,似乎TcpOutboundGateway不知道输入请求什么,但在消息处理器链被注册,而且每当需要的叫法。所以,现在看起来这不是一个简单的解决方案。
如果您有任何想法如何更改标记<int-ip:tcp-outbound-gateway>
使用的类,或者您有任何想法如何以完全不同的方式解决主超时问题,请告知。
谢谢。
答案 0 :(得分:0)
有趣的问题。
(正确)AsyncReply
对象不知道原始出站消息是正确的。
我们可以做的一件事是添加remote-timeout-expression
并根据消息计算超时......
AsyncReply reply = new AsyncReply(calculateReplyTimeout(requestMessage));
与此同时,如果您想自定义网关,可以轻松实现。
虽然命名空间(<int-ip:...
)不支持自定义类,但您始终可以使用<bean/>
连接网关。
您需要ConsumerEndpointFactoryBean
,并在其handler
媒体资源中获取自定义网关。