TCP 閘道器
入站 TCP 閘道器 TcpInboundGateway
和出站 TCP 閘道器 TcpOutboundGateway
分別使用伺服器和客戶端連線工廠。每個連線一次只能處理一個請求或響應。
入站閘道器在根據收到的 payload 構造訊息並將其傳送到 requestChannel
後,會等待響應,然後透過將響應訊息中的 payload 寫入連線來發送響應。
對於入站閘道器,您必須保留或填充 ip_connectionId 訊息頭,因為它用於將訊息與連線關聯。從閘道器發起的訊息會自動設定此訊息頭。如果回覆是作為新訊息構造的,則需要設定該訊息頭。訊息頭的值可以從入站訊息中捕獲。 |
與入站介面卡一樣,入站閘道器通常使用 type="server"
連線工廠,該工廠監聽入站連線請求。在某些情況下,您可能希望反向建立連線,即入站閘道器連線到外部伺服器,然後在該連線上等待並回復入站訊息。
透過在入站閘道器上使用 client-mode="true"
來支援這種拓撲。在這種情況下,連線工廠必須是 client
型別,並且 single-use
必須設定為 false
。
另外兩個屬性支援此機制。retry-interval
指定(以毫秒為單位)框架在連線失敗後嘗試重新連線的頻率。scheduler
提供一個 TaskScheduler
來排程連線嘗試並測試連線是否仍處於活動狀態。
如果閘道器已啟動,您可以透過傳送 <control-bus/>
命令 @adapter_id.retryConnection()
強制閘道器建立連線,並使用 @adapter_id.isClientModeConnected()
檢視當前狀態。
出站閘道器在透過連線傳送訊息後,會等待響應,構造一個響應訊息,並將其放入回覆通道。連線上的通訊是單執行緒的。一次只能處理一條訊息。如果在收到當前響應之前另一個執行緒嘗試傳送訊息,它將阻塞,直到之前的請求完成(或超時)。但是,如果客戶端連線工廠配置為單次使用連線,則每個新請求都會獲得自己的連線並立即處理。以下示例配置了一個入站 TCP 閘道器
<int-ip:tcp-inbound-gateway id="inGateway"
request-channel="tcpChannel"
reply-channel="replyChannel"
connection-factory="cfServer"
reply-timeout="10000"/>
如果使用配置了預設序列化器或反序列化器的連線工廠,訊息將是 \r\n
分隔的資料,並且閘道器可以被 telnet 等簡單客戶端使用。
以下示例展示了一個出站 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 時會忽略此屬性,因為存在競態條件,即在收到回覆後發生的 socket 錯誤可能在回覆到達閘道器之前被傳遞給閘道器。
使用共享連線(singleUse=false )時,如果另一個請求正在處理中,新請求將被阻塞,直到收到當前回覆。如果您希望在長連線池上支援併發請求,請考慮使用 CachingClientConnectionFactory 。 |
從 5.4 版本開始,入站閘道器可以配置 unsolicitedMessageChannel
。未經請求的入站訊息以及延遲的回覆(客戶端超時)將傳送到此通道。為了在伺服器端支援這一點,您現在可以向連線工廠註冊多個 TcpSender
。閘道器和通道介面卡會自動註冊。從伺服器傳送未經請求的訊息時,必須向傳送的訊息新增相應的 IpHeaders.CONNECTION_ID
。
另請參閱 基於註解的配置 和 使用 Java DSL 配置 TCP 元件。