UDP 介面卡

本節介紹如何配置和使用 UDP 介面卡。

出站 UDP 介面卡 (XML 配置)

以下示例配置了一個 UDP 出站通道介面卡

<int-ip:udp-outbound-channel-adapter id="udpOut"
    host="somehost"
    port="11111"
    multicast="false"
    socket-customizer="udpCustomizer"
    channel="exampleChannel"/>
當將 multicast 設定為 true 時,您還應該在主機屬性中提供多播地址。

UDP 是一種高效但不不可靠的協議。Spring Integration 添加了兩個屬性來提高可靠性:check-lengthacknowledge。當 check-length 設定為 true 時,介面卡在訊息資料之前新增一個長度欄位(網路位元組順序的四個位元組)。這使得接收方能夠驗證接收到的資料包的長度。如果接收系統使用的緩衝區太短而無法容納資料包,則資料包可能會被截斷。length 頭提供了一種檢測這種情況的機制。

從 4.3 版本開始,您可以將 port 設定為 0,在這種情況下,作業系統會選擇埠。在介面卡啟動且 isListening() 返回 true 後,可以透過呼叫 getPort() 來發現所選埠。

從 5.3.3 版本開始,您可以新增一個 SocketCustomizer bean,以便在建立 DatagramSocket 後對其進行修改(例如,呼叫 setTrafficClass(0x10))。

以下示例顯示了一個出站通道介面卡,它向資料報包添加了長度檢查

<int-ip:udp-outbound-channel-adapter id="udpOut"
    host="somehost"
    port="11111"
    multicast="false"
    check-length="true"
    channel="exampleChannel"/>
資料包的接收方也必須配置為期望在實際資料之前有一個長度。對於 Spring Integration UDP 入站通道介面卡,請設定其 check-length 屬性。

第二個可靠性改進允許使用應用程式級確認協議。接收方必須在指定時間內向傳送方傳送確認。

以下示例顯示了一個出站通道介面卡,它向資料報包添加了長度檢查並等待確認

<int-ip:udp-outbound-channel-adapter id="udpOut"
    host="somehost"
    port="11111"
    multicast="false"
    check-length="true"
    acknowledge="true"
    ack-host="thishost"
    ack-port="22222"
    ack-timeout="10000"
    channel="exampleChannel"/>
acknowledge 設定為 true 意味著資料包的接收方可以解釋新增到包含確認資料(主機和埠)的資料包中的頭。最有可能的是,接收方是一個 Spring Integration 入站通道介面卡。
當多播為 true 時,一個附加屬性 (min-acks-for-success) 指定在 ack-timeout 內必須收到多少個確認。

從 4.3 版本開始,您可以將 ackPort 設定為 0,在這種情況下,作業系統會選擇埠。

出站 UDP 介面卡 (Java 配置)

以下示例展示瞭如何使用 Java 配置出站 UDP 介面卡

@Bean
@ServiceActivator(inputChannel = "udpOut")
public UnicastSendingMessageHandler handler() {
    return new UnicastSendingMessageHandler("localhost", 11111);
}

(或用於多播的 MulticastSendingChannelAdapter)。

出站 UDP 介面卡 (Java DSL 配置)

以下示例展示瞭如何使用 Java DSL 配置出站 UDP 介面卡

@Bean
public IntegrationFlow udpOutFlow() {
    return f -> f.handle(Udp.outboundAdapter("localhost", 1234)
                    .configureSocket(socket -> socket.setTrafficClass(0x10)))
                .get();
}

入站 UDP 介面卡 (XML 配置)

以下示例展示瞭如何配置基本的單播入站 UDP 通道介面卡。

<int-ip:udp-inbound-channel-adapter id="udpReceiver"
    channel="udpOutChannel"
    port="11111"
    receive-buffer-size="500"
    multicast="false"
    socket-customizer="udpCustomizer"
    check-length="true"/>

以下示例展示瞭如何配置基本的多播入站 UDP 通道介面卡

<int-ip:udp-inbound-channel-adapter id="udpReceiver"
    channel="udpOutChannel"
    port="11111"
    receive-buffer-size="500"
    multicast="true"
    multicast-address="225.6.7.8"
    check-length="true"/>

預設情況下,入站資料包不執行反向 DNS 查詢:在未配置 DNS 的環境中(例如 Docker 容器),這可能導致連線延遲。要將 IP 地址轉換為用於訊息頭的主機名,可以透過將 lookup-host 屬性設定為 true 來覆蓋預設行為。

從 5.3.3 版本開始,您可以新增一個 SocketCustomizer bean,以便在建立 DatagramSocket 後對其進行修改。它適用於接收套接字和為傳送確認而建立的任何套接字。

入站 UDP 介面卡 (Java 配置)

以下示例展示瞭如何使用 Java 配置入站 UDP 介面卡

@Bean
public UnicastReceivingChannelAdapter udpIn() {
    UnicastReceivingChannelAdapter adapter = new UnicastReceivingChannelAdapter(11111);
    adapter.setOutputChannelName("udpChannel");
    return adapter;
}

以下示例展示瞭如何使用 Java DSL 配置入站 UDP 介面卡

入站 UDP 介面卡 (Java DSL 配置)

@Bean
public IntegrationFlow udpIn() {
    return IntegrationFlow.from(Udp.inboundAdapter(11111))
            .channel("udpChannel")
            .get();
}

伺服器監聽事件

從 5.0.2 版本開始,當入站介面卡啟動並開始監聽時,會發出 UdpServerListeningEvent。當介面卡配置為監聽埠 0(意味著作業系統選擇埠)時,這很有用。如果您需要在啟動將連線到套接字的其他程序之前進行等待,也可以使用它代替輪詢 isListening()

高階出站配置

<int-ip:udp-outbound-channel-adapter> (UnicastSendingMessageHandler) 具有 destination-expressionsocket-expression 選項。

您可以將 destination-expression 作為硬編碼 host-port 對的執行時替代方案,以根據 requestMessage(作為評估上下文的根物件)確定出站資料報包的目標地址。該表示式必須解析為 URI、URI 風格的 String(請參閱 RFC-2396)或 SocketAddress。您還可以使用入站 IpHeaders.PACKET_ADDRESS 頭作為此表示式。在框架中,當我們在 UnicastReceivingChannelAdapter 中接收資料報並將其轉換為訊息時,DatagramPacketMessageMapper 會填充此頭。頭值正是入站資料報的 DatagramPacket.getSocketAddress() 的結果。

透過 socket-expression,出站通道介面卡可以使用(例如)入站通道介面卡套接字透過接收它們相同的埠傳送資料報。這在我們的應用程式作為 UDP 伺服器且客戶端在網路地址轉換 (NAT) 後操作的場景中很有用。此表示式必須解析為 DatagramSocketrequestMessage 用作評估上下文的根物件。您不能將 socket-expression 引數與 multicastacknowledge 引數一起使用。以下示例展示瞭如何配置一個 UDP 入站通道介面卡,其中包含一個將轉換為大寫並使用套接字的轉換器

<int-ip:udp-inbound-channel-adapter id="inbound" port="0" channel="in" />

<int:channel id="in" />

<int:transformer expression="new String(payload).toUpperCase()"
                       input-channel="in" output-channel="out"/>

<int:channel id="out" />

<int-ip:udp-outbound-channel-adapter id="outbound"
                        socket-expression="@inbound.socket"
                        destination-expression="headers['ip_packetAddress']"
                        channel="out" />

以下示例展示了使用 Java DSL 的等效配置

@Bean
public IntegrationFlow udpEchoUpcaseServer() {
    return IntegrationFlow.from(Udp.inboundAdapter(11111).id("udpIn"))
            .<byte[], String>transform(p -> new String(p).toUpperCase())
            .handle(Udp.outboundAdapter("headers['ip_packetAddress']")
                    .socketExpression("@udpIn.socket"))
            .get();
}
© . This site is unofficial and not affiliated with VMware.