TCP Gateways

输入 TCP 网关 TcpInboundGateway 和输出 TCP 网关 TcpOutboundGateway 分别使用服务器和客户端连接工厂。每个连接一次只能处理单个请求或响应。

The inbound TCP gateway TcpInboundGateway and outbound TCP gateway TcpOutboundGateway use a server and client connection factory, respectively. Each connection can process a single request or response at a time.

在通过传入有效负载构建消息并将其发送到 requestChannel 后,输入网关将等待响应,并通过将有效负载从响应消息中写入连接来发送响应消息的有效负载。

The inbound gateway, after constructing a message with the incoming payload and sending it to the requestChannel, waits for a response and sends the payload from the response message by writing it to the connection.

对于入站网关,你必须保留或填充 ip_connectionId 头,因为它用于将消息与连接关联起来。在网关发起的邮件自动设置标头。如果答复构建为一条新消息,则需要设置标头。标头值可以从传入消息中捕获。

For the inbound gateway, you must retain or populate, the ip_connectionId header, because it is used to correlate the message to a connection. Messages that originate at the gateway automatically have the header set. If the reply is constructed as a new message, you need to set the header. The header value can be captured from the incoming message.

与输入适配器一样,输入网关通常使用 type="server" 连接工厂,该工厂侦听传入的连接请求。在某些情况下,您可能希望反向建立连接,例如,输入网关连接到外部服务器,然后等待并回复该连接上的传入消息。

As with inbound adapters, inbound gateways normally use a type="server" connection factory, which listens for incoming connection requests. In some cases, you may want to establish the connection in reverse, such that the inbound gateway connects to an external server and then waits for and replies to inbound messages on that connection.

输入网关上的 client-mode="true" 支持此拓扑。在这种情况下,连接工厂必须是 client 类型的,并且必须将 single-use 设置为 false

This topology is supported by using client-mode="true" on the inbound gateway. In this case, the connection factory must be of type client and must have single-use set to false.

还有两个附加属性支持此机制。retry-interval(以毫秒为单位)指定框架在连接失败后尝试重新连接的频率。scheduler 提供一个 TaskScheduler 来调度连接尝试并测试连接是否仍然处于活动状态。

Two additional attributes support this mechanism. The retry-interval specifies (in milliseconds) how often the framework tries to reconnect after a connection failure. The scheduler supplies a TaskScheduler to schedule the connection attempts and to test that the connection is still active.

如果网关已启动,您可以通过发送 <control-bus/> 命令强制网关建立连接:@adapter_id.retryConnection(),并使用 @adapter_id.isClientModeConnected() 检查当前状态。

If the gateway is started, you may force the gateway to establish a connection by sending a <control-bus/> command: @adapter_id.retryConnection() and examine the current state with @adapter_id.isClientModeConnected().

outbound 网关在通过连接发送消息之后,将等待响应、构建响应消息,并将其放在 reply 通道上。连接上的通信是单线程的。一次只能处理一个消息。如果另一个线程尝试在收到当前响应之前发送消息,它将阻塞,直至任何先前的请求完成(或超时)。但是,如果客户端连接工厂配置为仅限单次使用的连接,则每个新请求都会获取其自己的连接并立即处理。以下示例配置了一个 inbound TCP 网关:

The outbound gateway, after sending a message over the connection, waits for a response, constructs a response message, and puts it on the reply channel. Communications over the connections are single-threaded. Only one message can be handled at a time. If another thread attempts to send a message before the current response has been received, it blocks until any previous requests are complete (or time out). If, however, the client connection factory is configured for single-use connections, each new request gets its own connection and is processed immediately. The following example configures an inbound TCP gateway:

<int-ip:tcp-inbound-gateway id="inGateway"
    request-channel="tcpChannel"
    reply-channel="replyChannel"
    connection-factory="cfServer"
    reply-timeout="10000"/>

如果使用配置了默认序列化器或反序列化器的连接工厂,message 将是 \r\n 分隔数据,网关可以由 telnet 等简单客户端使用。

If a connection factory configured with the default serializer or deserializer is used, messages is \r\n delimited data and the gateway can be used by a simple client such as telnet.

以下示例显示了一个 outbound TCP 网关:

The following example shows an outbound TCP gateway:

<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 当前在 outbound 网关中不可用。

The client-mode is not currently available with the outbound gateway.

从 5.2 版开始,outbound 网关可以用 closeStreamAfterSend 属性配置。如果连接工厂配置为 single-use(每个请求/回复一个新连接),则网关会关闭输出流;这向服务器发出 EOF 信号。如果服务器使用 EOF 来确定消息的结尾,而不是流中的某个分隔符,但保持连接处于打开状态以接收回复,则这很有用。

Starting with version 5.2, the outbound gateway can be configured with the property closeStreamAfterSend. If the connection factory is configured for single-use (a new connection for each request/reply) the gateway will close the output stream; this signals EOF to the server. This is useful if the server uses the EOF to determine the end of message, rather than some delimiter in the stream, but leaves the connection open in order to receive the reply.

通常,调用线程会在网关中阻塞,等待回复(或超时)。从 5.3 版开始,你可以在网关上设置 async 属性,并且发送线程将被释放以执行其他工作。回复(或错误)将在接收线程上发送。这仅适用于使用 TcpNetClientConnectionFactory 的情况,在使用 NIO 时它将被忽略,因为存在竞争条件,即在收到回复后发生的套接字错误可能会在回复之前传递到网关。

Normally, the calling thread will block in the gateway, waiting for the reply (or a timeout). Starting with version 5.3, you can set the async property on the gateway and the sending thread is released to do other work. The reply (or error) will be sent on the receiving thread. This only applies when using the TcpNetClientConnectionFactory, it is ignored when using NIO because there is a race condition whereby a socket error that occurs after the reply is received can be passed to the gateway before the reply.

当使用共享连接(singleUse=false)时,在另一个处理过程中,新请求将被阻塞,直到收到当前答复为止。如果你希望在长期连接池上支持并发请求,请考虑使用 CachingClientConnectionFactory

When using a shared connection (singleUse=false), a new request, while another is in process, will be blocked until the current reply is received. Consider using the CachingClientConnectionFactory if you wish to support concurrent requests on a pool of long-lived connections.

从 5.4 版开始,inbound 可以用 unsolicitedMessageChannel 配置。主动的 inbound 消息将发送到此通道,以及延迟的回复(其中客户端超时)。为了在服务器端支持这一点,你现在可以使用连接工厂注册多个 TcpSender。网关和通道适配器会自动注册它们自己。从服务器发送主动消息时,你必须向发送的消息添加适当的 IpHeaders.CONNECTION_ID

Starting with version 5.4, the inbound can be configured with an unsolicitedMessageChannel. Unsolicited inbound messages will be sent to this channel, as well as late replies (where the client timed out). To support this on the server side, you can now register multiple TcpSender s with the connection factory. Gateways and Channel Adapters automatically register themselves. When sending unsolicited messages from the server, you must add the appropriate IpHeaders.CONNECTION_ID to the messages sent.