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

springboot框架对接物联网,配置TCP协议依赖,与设备通信,让TCP变的如此简单

最近在使用 Spring Boot 对接物联网设备,需要通过 TCP 协议进行通信。调研过程中发现,如果使用 Netty 框架并集成到 Spring Boot 中,配置和维护相对较为复杂。综合考虑后,最终选择了 Spring Integration 提供的 TCP/UDP 模块来实现相关功能,整体集成更加简洁,也更符合 Spring 生态的使用习惯。
第一步:
引入依赖

<dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-ip</artifactId></dependency>

第二步:
提供两个tcp服务端类文件,这两个类文件大家按需选择即可。
第一个类文件:
单向接收tcp客户端数据:

package com.testweb.testweb.tcp.web;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.integration.annotation.ServiceActivator;importorg.springframework.integration.channel.DirectChannel;importorg.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;importorg.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;importorg.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory;importorg.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer;importorg.springframework.messaging.Message;importorg.springframework.messaging.MessageChannel;importjava.nio.charset.StandardCharsets;@Slf4j @Configuration public class TcpServerConfig{@Value("${tcp.server.port:7788}")private int port;/** *1. TCP 连接工厂(服务端) */ @Bean public AbstractServerConnectionFactoryserverConnectionFactory(){TcpNioServerConnectionFactory factory=new TcpNioServerConnectionFactory(port);// 关键:拆包 / 粘包解决方案(行结束符) // 按换行符(\r\n 或\n)拆包,常用于文本协议 ByteArrayCrLfSerializer serializer=new ByteArrayCrLfSerializer();// 二进制协议示例:长度头 + 消息内容(常用于物联网) // ByteArrayLengthHeaderSerializer serializer=// new ByteArrayLengthHeaderSerializer();factory.setSerializer(serializer);factory.setDeserializer(serializer);factory.setUsingDirectBuffers(true);returnfactory;}/** *2. 接收同步通道 */ @Bean public MessageChanneltcpReceiveChannel(){returnnew DirectChannel();}/** *3. TCP 入站适配器(只接收) */ @Bean public TcpReceivingChannelAdapter tcpInboundAdapter(AbstractServerConnectionFactory factory, MessageChannel tcpReceiveChannel){TcpReceivingChannelAdapter adapter=new TcpReceivingChannelAdapter();adapter.setConnectionFactory(factory);adapter.setOutputChannel(tcpReceiveChannel);returnadapter;}/** *4. 业务处理器(单向接收,不能给客户端回复) */ @ServiceActivator(inputChannel="tcpReceiveChannel")public void handleMessage(Message<byte[]>message){String data=new String(message.getPayload(), StandardCharsets.UTF_8);String connectionId=(String)message.getHeaders().get("ip_connectionId");log.info("收到 TCP 数据: {}", data);log.info("来自连接: {}", connectionId);// TODO 业务逻辑处理}}

第二个类文件:
双向类文件:接收客户端消息并回复

package com.testweb.testweb.tcp.web;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.annotation.Qualifier;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.integration.annotation.ServiceActivator;importorg.springframework.integration.channel.DirectChannel;importorg.springframework.integration.ip.tcp.TcpReceivingChannelAdapter;importorg.springframework.integration.ip.tcp.TcpSendingMessageHandler;importorg.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;importorg.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory;importorg.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer;importorg.springframework.messaging.Message;importorg.springframework.messaging.MessageChannel;importjava.nio.charset.StandardCharsets;@Slf4j @Configuration public class TcpServerReplyConfig{@Value("${tcp.server.reply.port:7799}")// 与单向服务端端口区分 private int port;// 回复通道 @Autowired @Qualifier("tcpReplySendChannel")private MessageChannel tcpReplySendChannel;/** *1. TCP 连接工厂(服务端) */ @Bean public AbstractServerConnectionFactoryreplyServerConnectionFactory(){TcpNioServerConnectionFactory factory=new TcpNioServerConnectionFactory(port);// 关键:拆包 / 粘包解决方案 // 使用换行符拆包(文本协议)或长度头(物联网二进制协议) ByteArrayCrLfSerializer serializer=new ByteArrayCrLfSerializer();// ByteArrayLengthHeaderSerializer serializer=// new ByteArrayLengthHeaderSerializer();factory.setSerializer(serializer);factory.setDeserializer(serializer);factory.setUsingDirectBuffers(true);returnfactory;}/** *2. 接收通道 */ @Bean public MessageChanneltcpReplyReceiveChannel(){returnnew DirectChannel();}/** *3. TCP 入站适配器(接收客户端消息) */ @Bean public TcpReceivingChannelAdapter tcpReplyInboundAdapter(AbstractServerConnectionFactory replyServerConnectionFactory, MessageChannel tcpReplyReceiveChannel){TcpReceivingChannelAdapter adapter=new TcpReceivingChannelAdapter();adapter.setConnectionFactory(replyServerConnectionFactory);adapter.setOutputChannel(tcpReplyReceiveChannel);returnadapter;}/** *4. TCP 出站通道(用于回复客户端) */ @Bean("tcpReplySendChannel")public MessageChanneltcpReplySendChannel(){returnnew DirectChannel();}/** *5. 出站适配器(发送回复) */ @Bean @ServiceActivator(inputChannel="tcpReplySendChannel")public TcpSendingMessageHandler tcpReplySender(AbstractServerConnectionFactory replyServerConnectionFactory){TcpSendingMessageHandler sender=new TcpSendingMessageHandler();sender.setConnectionFactory(replyServerConnectionFactory);returnsender;}/** *6. 业务处理器:接收客户端消息并回复 */ @ServiceActivator(inputChannel="tcpReplyReceiveChannel")public void handleReplyMessage(Message<byte[]>message){String data=new String(message.getPayload(), StandardCharsets.UTF_8);String connectionId=(String)message.getHeaders().get("ip_connectionId");log.info("收到客户端消息: {}", data);log.info("来自连接: {}", connectionId);// 业务逻辑处理完后发送回复 String reply="服务端已经收到消息,现在给客户端回复: "+ data;tcpReplySendChannel.send(org.springframework.messaging.support.MessageBuilder .withPayload(reply.getBytes(StandardCharsets.UTF_8)).setHeader("ip_connectionId", connectionId).build());}}

这两个配置文件 大家可以按需选择。第一个类文件就是服务端只负责接收,不会给客户端反馈
第二个类文件,接收后会反馈,如果在使用中发现有需要完善的地方,也欢迎大家留言~

http://www.rkmt.cn/news/117730.html

相关文章:

  • 软件测试环境搭建全流程指南
  • 中国储能第一股赴美IPO,但工厂也得搬过去
  • Model Context Protocol(MCP)简介以及简单示例代码测试(.net8)
  • GitLab讲解
  • 用长短期记忆网络融合注意力机制做时间序列预测,效果惊人
  • 在Linux系统上一键配置DoH,解决DNS解析被污染
  • 12.17学习例题(1)
  • 提示词工程完全指南(超详细)从零基础到精通,一篇就够,建议收藏!
  • C2000,28335Matlab/Simulink代码生成技术,处理器在环,里面有电力电子常...
  • const是什么
  • 大模型新手必看:入门经验分享,助你快速成长,少走三年弯路!
  • 一款实用的Windows自动更新管理器--WAU 管理器,v3.8.3.0新版本,中文便携版~
  • YC创业名录:精准对接高潜力初创公司
  • ManySpeech —— 使用 C# 开发人工智能语音应用
  • 基于大数据的社交网络隐私保护及舆情分析可视化系统开题报告
  • Vue3利用ResizeObserver监听Textarea的尺寸动态调整表格tbody的maxHeight
  • 论文文献引用格式最新规范流出,毕业季限时必看!
  • SpringBoot使用设计模式一装饰器模式
  • 从零构建AI镜像,缓存命中率提升至95%的3个核心技巧
  • Java 大视界 -- Java 大数据在智能家居能源管理与节能优化中的深度应用
  • 基于java的SpringBoot/SSM+Vue+uniapp的仓储管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
  • 基于大数据的热点话题分析系统的设计与实开题报告 (1)
  • 如何解决 pip install 网络报错 ERROR: No matching distribution found for requests
  • FreeIPA能建立用户组,并将域组带入到加域的客户端
  • 基于大数据的热点话题分析系统的设计与实开题报告
  • 【值得收藏】RAG技术全解析:大模型检索增强生成的挑战、范式与优化策略
  • 超越规范:测试标准如何成为你的效率引擎,而非发展枷锁?
  • 你不知道的Q#调试黑科技:如何让Python端实时捕获量子状态异常
  • Windwos 内存被占用,但是任务管理器没有占用这么多,
  • 网络安全零基础入门怎么学?超详细学习指南在此,带你一站式从入门到精通!