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()
檢查目前狀態。
輸出閘道在透過連線傳送訊息後,會等待回應,建構回應訊息,並將其放入回覆通道。透過連線的通訊是單執行緒的。一次只能處理一則訊息。如果另一個執行緒嘗試在收到目前回應之前傳送訊息,它會封鎖,直到先前的請求完成(或逾時)。但是,如果為單次使用連線配置用戶端連線工廠,則每個新請求都會取得自己的連線並立即處理。以下範例設定輸入 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 元件。