TCP 网关
入站 TCP 网关 TcpInboundGateway
和出站 TCP 网关 TcpOutboundGateway
分别使用服务器和客户端连接工厂。每个连接一次可以处理一个请求或响应。
入站网关在使用传入的有效负载构建消息并将其发送到 requestChannel
后,会等待响应,并通过将响应消息的有效负载写入连接来发送它。
对于入站网关,您必须保留或填充 ip_connectionId
标头,因为它用于将消息关联到连接。起源于网关的消息会自动设置此标头。如果回复是作为新消息构造的,则需要设置该标头。可以从传入消息中捕获标头值。
与入站适配器一样,入站网关通常使用 type="server"
连接工厂,以监听传入的连接请求。在某些情况下,您可能希望反向建立连接,即入站网关连接到外部服务器,然后在此连接上等待并回复入站消息。
此拓扑通过在入站网关上使用 client-mode="true"
来支持。在这种情况下,连接工厂必须是 client
类型,并且必须将 single-use
设置为 false
。
两个附加属性支持此机制。retry-interval
指定(以毫秒为单位)框架在连接失败后尝试重新连接的频率。scheduler
提供一个 TaskScheduler
来安排连接尝试并测试连接是否仍然有效。
如果网关已启动,您可以通过发送一个 <control-bus/>
命令来强制网关建立连接:@adapter_id.retryConnection()
,并使用 @adapter_id.isClientModeConnected()
检查当前状态。
outbound 网关在通过连接发送消息后,会等待响应,构造响应消息,并将其放在回复通道上。连接上的通信是单线程的。一次只能处理一条消息。如果另一个线程试图在当前响应未收到之前发送消息,则它会阻塞,直到任何先前的请求完成(或超时)。但是,如果客户端连接工厂配置为单次使用连接,每个新请求都会获得自己的连接并立即处理。以下示例配置了一个入站 TCP 网关:
<int-ip:tcp-inbound-gateway id="inGateway"
request-channel="tcpChannel"
reply-channel="replyChannel"
connection-factory="cfServer"
reply-timeout="10000"/>
如果使用默认序列化程序或反序列化程序配置的连接工厂,则消息是以 \r\n
分隔的数据,网关可以被类似 telnet 的简单客户端使用。
以下示例显示了一个 outbound TCP 网关:
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="tcpChannel"
reply-channel="replyChannel"
connection-factory="cfClient"
request-timeout="10000"
remote-timeout="10000"/> <!-- or e.g. remote-timeout-expression="headers['timeout']" -->
client-mode
目前尚未在外发网关中提供。
从 5.2 版本开始,可以使用属性 closeStreamAfterSend
配置出站网关。如果连接工厂配置为 single-use
(每次请求/回复创建一个新的连接),网关将关闭输出流;这会向服务器发出 EOF 信号。如果服务器使用 EOF 来确定消息的结束,而不是流中的某些定界符,但保持连接打开以接收回复,这将非常有用。
通常情况下,调用线程会在网关中阻塞,等待回复(或超时)。从 5.3 版本开始,你可以在网关上设置 async
属性,这样发送线程将被释放以执行其他工作。回复(或错误)将在接收线程上发送。这仅适用于使用 TcpNetClientConnectionFactory
时,在使用 NIO 时会被忽略,因为存在一个竞争条件,即在收到回复之后发生的套接字错误可能会在回复之前传递给网关。
当使用共享连接 (singleUse=false
) 时,如果另一个请求正在处理中,新的请求将被阻塞,直到收到当前的回复。如果您希望在长生命周期连接池上支持并发请求,请考虑使用 CachingClientConnectionFactory
。
从 5.4 版本开始,入站连接可以配置 unsolicitedMessageChannel
。未请求的入站消息将被发送到此通道,以及迟到的回复(客户端超时的情况)。为了在服务器端支持这一点,您现在可以在连接工厂中注册多个 TcpSender
。网关和通道适配器会自动注册自己。当从服务器发送未请求的消息时,您必须在发送的消息中添加适当的 IpHeaders.CONNECTION_ID
。
也请参阅 基于注解的配置 和 使用 Java DSL 进行 TCP 组件配置。