当前位置: 首页 > news >正文

spring通过Spring Integration实现udp通信

1:Spring Integration UDP 的优势

        Spring Integration 对 UDP 的封装,让你能通过简单的配置和注解就实现消息的接收、转换、过滤、路由和处理,无需过多关心底层 Socket 的复杂性。它支持单播(Unicast) 和多播(Multicast),并且提供了消息长度检查和确认机制来一定程度提升 UDP 的可靠性。

2:消息处理流程

        

3:具体实现

        1):导入依赖

<!-- spring-integration -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId><version>2.5.15</version>
</dependency>
<dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-ip</artifactId><version>5.5.18</version>
</dependency>

        2)在配置文件中配置udp端口

# 测试udp
cs:udp:# 接收端口receive-port: 1234# 发送端口send-port: 1235

        3)创建消息处理流程

package **.**;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.Filter;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.ip.dsl.Udp;
import org.springframework.integration.ip.udp.UnicastSendingMessageHandler;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;import java.nio.charset.StandardCharsets;
import java.util.Map;@Configuration
public class UdpIntegrationConfig {@Value("${cs.udp.receive-port}")private Integer recivePort;@Value("${cs.udp.send-port}")private Integer sendPort;/*** 定义接收流程*/@Beanpublic IntegrationFlow udpInboundFlow() {return IntegrationFlows.from(Udp.inboundAdapter(recivePort)) // 创建UDP入站适配器,监听指定端口.channel("udpChannel") // 指定接收通道.get();}/*** 转换器 (Transformer)* 将接收到的 byte[] payload 转换为 String* 输出到 udpFilterChannel*/@Transformer(inputChannel = "udpChannel", outputChannel = "udpFilterChannel")public String transformer(@Payload byte[] payload, @Headers Map<String, Object> headers) {String message = new String(payload, StandardCharsets.UTF_8); // 指定编码,避免乱码// 这里可以进行必要的转换,例如JSON解析等System.out.println("----------------------------" + message);return message;}/*** 过滤器 (Filter)* 决定哪些消息需要继续处理* 输出到 udpRouterChannel*/@Filter(inputChannel = "udpFilterChannel", outputChannel = "udpRouterChannel")public boolean filter(String message, @Headers Map<String, Object> headers) {// 获取来源信息,可用于过滤String sourceIp = headers.get("ip_address").toString();String sourcePort = headers.get("ip_port").toString();// 示例:简单过滤掉空消息或包含特定关键字的消息if (message == null || message.trim().isEmpty() || message.contains("DROP")) {return false; // 消息将被丢弃}return true; // 消息继续向下流转}/*** 路由器 (Router)* 根据消息内容或头信息决定将消息发送到哪个处理器*/@Router(inputChannel = "udpRouterChannel")public String router(String message, @Headers Map<String, Object> headers) {if (message.startsWith("ORDER:")) {return "udpOrderHandleChannel"; // 路由到订单处理器} else if (message.startsWith("LOG:")) {return "udpLogHandleChannel"; // 路由到日志处理器} else {return "udpDefaultHandleChannel"; // 路由到默认处理器}}/*** 最终处理器 (Service Activator) - 处理订单消息*/@ServiceActivator(inputChannel = "udpOrderHandleChannel")public void handleOrder(String message) {// 这里处理订单逻辑System.out.println("Processing order: " + message);}/*** 最终处理器 (Service Activator) - 处理日志消息*/@ServiceActivator(inputChannel = "udpLogHandleChannel")public void handleLog(String message) {// 这里处理日志逻辑System.out.println("Processing log: " + message);}/*** 最终处理器 (Service Activator) - 处理默认消息:cite[3]* 通常这是你最常用的处理器*/@ServiceActivator(inputChannel = "udpDefaultHandleChannel")public void handleDefaultMessage(String message, @Headers Map<String, Object> headers) {// 这里是你的核心业务逻辑String sourceIp = headers.get("ip_address").toString();String sourcePort = headers.get("ip_port").toString();System.out.println("Received UDP message from " + sourceIp + ":" + sourcePort + " - " + message);// TODO: 调用你的业务Service处理消息}/*** 配置 UDP 发送处理器 (出站适配器)*/@Beanpublic UnicastSendingMessageHandler udpSendingMessageHandler() {// 参数:目标主机、目标端口、是否启用长度检查(建议true)// TODO 正式使用时,此处需修改为发送端口return new UnicastSendingMessageHandler("localhost", recivePort, true);}}

        4)创建发送udp消息的接口

        

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.ip.udp.UnicastSendingMessageHandler;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/udp")
public class UdpSendController {@Autowiredprivate UnicastSendingMessageHandler udpSendingMessageHandler;@PostMapping("/send")public String sendUdpMessage(@RequestParam String message) {// 构建消息并发送Message<byte[]> messageToSend = MessageBuilder.withPayload(message.getBytes()).build();udpSendingMessageHandler.handleMessage(messageToSend);return "Message sent: " + message;}}

        5)测试

                启动项目,调用发送接口,看控制台是否能正确输出内容

                


文章转载自:

http://UPDnvjHw.dtpnb.cn
http://ZiJC9HkL.dtpnb.cn
http://MOsVg1qU.dtpnb.cn
http://auiG2v5M.dtpnb.cn
http://dqMIFUti.dtpnb.cn
http://5VRzHWCa.dtpnb.cn
http://DElY7rOG.dtpnb.cn
http://vnEjHXeG.dtpnb.cn
http://atpX4rcO.dtpnb.cn
http://tf3KkzVq.dtpnb.cn
http://PBn0hYPD.dtpnb.cn
http://4tzJKkmk.dtpnb.cn
http://t13HVAjV.dtpnb.cn
http://fERIySvo.dtpnb.cn
http://dALsc1T3.dtpnb.cn
http://1j429Onb.dtpnb.cn
http://uFRWNYvo.dtpnb.cn
http://zfqA5M5O.dtpnb.cn
http://sekfk1ud.dtpnb.cn
http://KKeCVudh.dtpnb.cn
http://Czm30i77.dtpnb.cn
http://r8E8gTx7.dtpnb.cn
http://uXjapJxl.dtpnb.cn
http://E4vwcgNs.dtpnb.cn
http://e55ruhYi.dtpnb.cn
http://kfc7f5yO.dtpnb.cn
http://axon1vFg.dtpnb.cn
http://PoNq7H8i.dtpnb.cn
http://EAjOAwWy.dtpnb.cn
http://JBvlvryT.dtpnb.cn
http://www.dtcms.com/a/386207.html

相关文章:

  • Linux内存管理章节十八:内核开发者的武器库:内存分配API实战指南
  • CAD如何输出PDF多页文件
  • 我对 WPF 动摇时的选择:.NET Framework 4.6.2+WPF+Islands+UWP+CompostionApi
  • 1.整流-滤波电路的缺点和PFC的引入
  • QT 项目 线程信号切换 举例
  • 构网型5MW中压储能变流升压一体机技术方案
  • 【数据工程】8. SQL 入门教程
  • C++---前向声明
  • 在Qt项目中使用QtConcurrent::run,实现异步等待和同步调用
  • 经验分享只靠口头传递会带来哪些问题
  • Linux底层-内核数据接口:/proc
  • PEFT+DeepSpeed 1 (微调 分布式 显存优化)
  • Spring Boot 下 Druid 连接池:多维度优化打造卓越性能
  • 提升学术研究能力:从开题构思难题到AI辅助提纲生成
  • spring-kafka的消息拦截器RecordInterceptor
  • VSCode + Python 开发踩坑:虚拟环境不在项目根目录导致包无法识别该怎么办
  • 【MCP】【FastMCP】[特殊字符] 使用 UV 创建 FastMCP 服务完整示例
  • 蓝绿部署(Blue-Green Deployment)介绍(一种用于降低软件发布风险的部署策略)流量切换(金丝雀发布)
  • 羽毛球地板:从专业运动场景到全民健身市场的技术跃迁与产业重构
  • 【实战】预警算法--噪声添加机制
  • Three.js 中如何给 3D 模型添加文字标签?
  • 贪心算法应用:NFV功能部署问题详解
  • 第八章:Jmeter 非GUl命令详解
  • 知识点17:多Agent系统架构设计模式
  • 作为学术工作者,利用沁言学术提升效率:集成化与一站式体验
  • Linux网络设备驱动—netlink
  • C# 导出 Excel 时并行处理数据:10 万条数据分批次并行转换,导出时间缩短 60%
  • 设计模式(java实现)----原型模式
  • VBA 将多个相同格式EXCEL中内容汇总到一个EXCEL文件中去
  • Android系统基础:底层状态监听UEvent之UEventObserver源码分析