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-length と acknowledge の 2 つの属性を追加します。check-length が true に設定されている場合、アダプターはメッセージデータの前に長さフィールド(ネットワークバイト順で 4 バイト)を付けます。これにより、受信側は受信したパケットの長さを確認できます。受信システムが、パケットを格納するには短すぎるバッファを使用する場合、パケットは切り捨てられる可能性があります。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 属性を設定します。

2 番目の信頼性の向上により、アプリケーションレベルの確認応答プロトコルを使用できます。受信者は、指定された時間内に送信者に確認応答を送信する必要があります。

次の例は、データグラムパケットに長さチェックを追加し、確認応答を待機する送信チャネルアダプターを示しています。

<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 受信チャネルアダプターです。
マルチキャストが真である場合、追加の属性(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 で listen するように構成されている場合、つまりオペレーティングシステムがポートを選択する場合に役立ちます。ソケットに接続する他のプロセスを開始する前に待機する必要がある場合は、isListening() をポーリングする代わりに使用することもできます。

高度な送信設定

<int-ip:udp-outbound-channel-adapter> (UnicastSendingMessageHandler)には destination-expression および socket-expression オプションがあります。

ハードコードされた host-port ペアのランタイム代替として destination-expression を使用して、requestMessage に対する発信データグラムパケットの宛先アドレスを決定できます(評価コンテキストのルートオブジェクトを使用)。式は、URI、URI スタイルの String (RFC-2396 [IETF] (英語) を参照)、または SocketAddress に評価される必要があります。この式に受信 IpHeaders.PACKET_ADDRESS ヘッダーを使用することもできます。フレームワークでは、UnicastReceivingChannelAdapter でデータグラムを受信し、メッセージに変換すると、DatagramPacketMessageMapper がこのヘッダーにデータを入力します。ヘッダー値は、受信データグラムの DatagramPacket.getSocketAddress() の結果とまったく同じです。

socket-expression を使用すると、送信チャネルアダプターは(たとえば)受信チャネルアダプターソケットを使用して、受信したのと同じポートを介してデータグラムを送信できます。アプリケーションが UDP サーバーとして機能し、クライアントがネットワークアドレス変換(NAT)の背後で動作するシナリオで役立ちます。この式は DatagramSocket に評価される必要があります。requestMessage は、評価コンテキストのルートオブジェクトとして使用されます。socket-expression パラメーターを multicast および acknowledge パラメーターと一緒に使用することはできません。次の例は、大文字に変換し、ソケットを使用するトランスフォーマーで 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();
}