本节介绍如何配置和使用 UDP 适配器。Spring中文文档

出站 UDP 适配器(XML 配置)

以下示例配置 UDP 出站通道适配器:Spring中文文档

<int-ip:udp-outbound-channel-adapter id="udpOut"
    host="somehost"
    port="11111"
    multicast="false"
    socket-customizer="udpCustomizer"
    channel="exampleChannel"/>
设置为 时,还应在 host 属性中提供组播地址。multicasttrue

UDP 是一种高效但不可靠的协议。 Spring Integration 添加了两个属性以提高可靠性:和 。 当设置为 时,适配器在消息数据前面加上一个长度字段(网络字节顺序为 4 个字节)。 这使接收方能够验证接收的数据包的长度。 如果接收系统使用的缓冲区太短而无法容纳数据包,则数据包可能会被截断。 标头提供了一种机制来检测此情况。check-lengthacknowledgecheck-lengthtruelengthSpring中文文档

从版本 4.3 开始,您可以将 设置为 ,在这种情况下,操作系统会选择端口。 可以通过在适配器启动并返回 后调用来发现所选端口。port0getPort()isListening()trueSpring中文文档

从版本 5.3.3 开始,您可以在创建 Bean 后添加 Bean 进行修改(例如,调用 )。SocketCustomizerDatagramSocketsetTrafficClass(0x10)Spring中文文档

以下示例显示了向数据报数据包添加长度检查的出站通道适配器:Spring中文文档

<int-ip:udp-outbound-channel-adapter id="udpOut"
    host="somehost"
    port="11111"
    multicast="false"
    check-length="true"
    channel="exampleChannel"/>
数据包的接收方还必须配置为期望在实际数据之前有一个长度。 对于 Spring Integration UDP 入站通道适配器,请设置其属性。check-length

第二个可靠性改进允许使用应用程序级确认协议。 接收方必须在指定时间内向发送方发送确认。Spring中文文档

以下示例显示了一个出站通道适配器,该适配器向数据报数据包添加长度检查并等待确认:Spring中文文档

<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"/>
设置为意味着数据包的接收者可以解释添加到包含确认数据(主机和端口)的数据包中的标头。 最有可能的是,收件人是 Spring Integration 入站通道适配器。acknowledgetrue
当多播为 true 时,附加属性 () 指定在 中必须接收多少次确认。min-acks-for-successack-timeout

从版本 4.3 开始,您可以将 设置为 ,在这种情况下,操作系统会选择端口。ackPort0Spring中文文档

设置为 时,还应在 host 属性中提供组播地址。multicasttrue
数据包的接收方还必须配置为期望在实际数据之前有一个长度。 对于 Spring Integration UDP 入站通道适配器,请设置其属性。check-length
设置为意味着数据包的接收者可以解释添加到包含确认数据(主机和端口)的数据包中的标头。 最有可能的是,收件人是 Spring Integration 入站通道适配器。acknowledgetrue
当多播为 true 时,附加属性 () 指定在 中必须接收多少次确认。min-acks-for-successack-timeout

出站 UDP 适配器(Java 配置)

以下示例演示如何使用 Java 配置出站 UDP 适配器:Spring中文文档

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

(或用于组播)。MulticastSendingChannelAdapterSpring中文文档

出站 UDP 适配器(Java DSL 配置)

以下示例演示如何使用 Java DSL 配置出站 UDP 适配器:Spring中文文档

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

入站 UDP 适配器(XML 配置)

以下示例演示如何配置基本的单播入站 udp 通道适配器。Spring中文文档

<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 通道适配器:Spring中文文档

<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-hosttrueSpring中文文档

从 V5.3.3 开始,您可以在创建 Bean 后添加 Bean 进行修改。 它为接收套接字和为发送确认器创建的任何套接字调用。SocketCustomizerDatagramSocketSpring中文文档

入站 UDP 适配器(Java 配置)

以下示例说明如何使用 Java 配置入站 UDP 适配器:Spring中文文档

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

以下示例演示如何使用 Java DSL 配置入站 UDP 适配器:Spring中文文档

入站 UDP 适配器(Java DSL 配置)

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

服务器侦听事件

从版本 5.0.2 开始,当入站适配器启动并开始侦听时,将发出 a。 当适配器配置为侦听端口时,这很有用,这意味着操作系统选择端口。 如果您需要等待,则也可以使用它来代替轮询,然后再启动将连接到套接字的其他进程。UdpServerListeningEvent0isListening()Spring中文文档

高级出站配置

() 有 和 选项。<int-ip:udp-outbound-channel-adapter>UnicastSendingMessageHandlerdestination-expressionsocket-expressionSpring中文文档

您可以将 用作硬编码 - 对的运行时替代方案,以根据 a(使用评估上下文的根对象)确定传出数据报数据包的目标地址。 表达式的计算结果必须为 URI 样式的 、a (请参阅 RFC-2396) 或 . 还可以将入站标头用于此表达式。 在框架中,当我们在 中接收数据报并将它们转换为消息时,会填充此标头。 标头值正是传入数据报的结果。destination-expressionhostportrequestMessageURIStringSocketAddressIpHeaders.PACKET_ADDRESSDatagramPacketMessageMapperUnicastReceivingChannelAdapterDatagramPacket.getSocketAddress()Spring中文文档

使用 ,出站通道适配器可以使用(例如)入站通道适配器套接字通过接收数据报的同一端口发送数据报。 在我们的应用程序作为 UDP 服务器工作并且客户端在网络地址转换 (NAT) 后面运行的情况下,它非常有用。 此表达式的计算结果必须为 . 用作评估上下文的根对象。 不能将参数与 and 参数一起使用。 以下示例演示如何使用转换为大写并使用套接字的转换器配置 UDP 入站通道适配器:socket-expressionDatagramSocketrequestMessagesocket-expressionmulticastacknowledgeSpring中文文档

<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 的等效配置:Spring中文文档

@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();
}