Spring Integration UDP示例无回复致客户端挂起,如何实现应答?
在Spring Boot UDP服务中实现客户端回复
要解决客户端发送UDP消息后挂起的问题,核心是让服务端收到消息后向客户端返回确认回复。以下是具体实现步骤:
1. 修改UDP服务配置
将原有的单向接收适配器替换为支持回复的Spring Integration UDP入站适配器,它会自动将客户端地址信息携带到消息头中:
package com.wheresjim.udp.config import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.integration.dsl.IntegrationFlow import org.springframework.integration.dsl.Udp @Configuration class UdpConfig { private Integer port = 6767 @Bean IntegrationFlow processUdpMessage() { IntegrationFlow .from(Udp.inboundAdapter(port)) .handle("udpService", "receive") .get() } }
2. 修改消息处理器,返回回复内容
修改UdpService的receive方法,使其返回回复消息,并保留原消息头中的客户端地址信息,Spring Integration会自动将回复发送回客户端:
package com.wheresjim.udp.service import org.springframework.messaging.Message import org.springframework.messaging.support.MessageBuilder import org.springframework.stereotype.Component @Component class UdpService { Message<String> receive(Message<byte[]> message) { // 解析收到的UDP消息内容 String data = new String(message.getPayload()) System.out.println("收到客户端消息:" + data) // 构造自定义回复内容 String replyContent = "确认收到:" + data // 复制原消息头(包含客户端地址/端口),构造回复消息 return MessageBuilder.withPayload(replyContent) .copyHeaders(message.getHeaders()) .build() } }
3. 客户端代码优化(可选)
调整客户端代码,支持多次发送消息,并正确处理回复:
DatagramSocket socket = new DatagramSocket() InetAddress address = InetAddress.getByName('localhost') String sendUDP(String msg, InetAddress address, DatagramSocket socket) { byte[] buf = msg.getBytes() println "发送消息字节长度:" + buf.length // 发送消息到服务端 DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 6767) socket.send(packet) // 接收服务端回复 byte[] receiveBuf = new byte[1024] DatagramPacket receivePacket = new DatagramPacket(receiveBuf, receiveBuf.length) socket.receive(receivePacket) String received = new String(receivePacket.getData(), 0, receivePacket.getLength()) println "收到服务端回复:" + received return received } String testMsg = '<?xml version="1.0" encoding="UTF-8"?><TestMsg><Text>Hello World</Text></TestMsg>' // 测试发送多条消息 try { for (int i = 0; i < 3; i++) { sendUDP(testMsg + " (第" + (i+1) + "次发送)", address, socket) Thread.sleep(1000) } } catch (Exception e) { e.printStackTrace() } finally { socket.close() }
关键原理说明
Udp.inboundAdapter()会自动在收到的消息头中添加ip_remoteAddress(客户端地址)和ip_remotePort(客户端端口)属性。- 当处理器返回消息时,Spring Integration会读取这些头信息,自动将回复发送回对应的客户端地址,无需手动配置发送适配器。
- UDP是无连接协议,必须依赖每次消息携带的客户端地址完成回复,无法复用固定连接。
内容的提问来源于stack exchange,提问作者Jim Gough
相关产品推荐
相关产品推荐

