ThingsBoard如何接受设备通过TCP发送的报文

1、概述

2、案例

2.1、阐述

2.2、导入依赖

2.3、构建Netty服务链接,接受的端口为8092

2.4、对数据进行相应的处理发送到ThingsBoard客户端

2.5、通过TCP链接工具

​2.6、查看遥测数据


1、概述

TCP(Transmission Control Protocol,传输控制协议)是互联网中的一种面向连接的、可靠的、基于字节流的传输层通信协议。它提供了点对点的通信,并且可靠地传递数据。TCPInternet 协议族中最为重要、应用最为广泛的一种协议。

2、案例

ThinsBoard原生代码中,只支持 Coap、Https、Lwm2m、Mqtt、Snmp五种协议的传输格式,并不支持TCP的报文协议,但是很多场景下设备的发送协议就是TCP协议或者是UDP协议的情况,如何把这类的设备接收到ThingsBoard平台中,目前共有三种实现方式:

第一种 :通过外部服务将报文转换成ThingsBoard原生代码支持的协议进行发送 

第二种:通过ThingsBoard GateWay进行进行数据的转换

第三种:修改ThingsBoatd源码,创建Transport来支持TCP协议的数据

三种转换的方式各有利弊,再次并不推荐说那种好或者那种不好,本次文章只对第一种情况进行讲解,在不修改源代码的情况下,将TCP接收到的数据,发送到ThingsBoard平台

2.1、阐述

设备通过TCP发送消息,其实就是需要建立对应的Socket链接,我们使用Netty来暴露对应的端口,让设备往对应的端口上发送数据,服务接受到数据后,对数据进行解析,解析完成后,推送到ThingsBoard平台

2.2、导入依赖
        <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-all</artifactId>
                <version>4.1.63.Final</version>
            </dependency>
            <dependency>
                <groupId>org.eclipse.paho</groupId>
                <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
                <version>1.2.5</version>
            </dependency>
2.3、构建Netty服务链接,接受的端口为8092
package com.example.tpson_tcp;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

/**
 * Netty服务端类,用于启动TCP服务器。
 */
@Service
public class NettyServer {

    /**
     * 在对象初始化后自动调用的方法,用于启动服务器。
     * 无参数和返回值。
     */
    @PostConstruct
    public void main() {
        // 创建EventLoopGroup用于处理网络事件
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            // 配置服务器启动参数
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class) // 指定使用的NIO通道类
                    .childHandler(new ChannelInitializer<SocketChannel>() { // 设置通道初始化处理器
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            // 在通道中添加处理链,用于解码、编码和处理设备数据
                            ch.pipeline().addLast(new StringDecoder());
                            ch.pipeline().addLast(new StringEncoder());
                            ch.pipeline().addLast(new DeviceDataHandler());
                        }
                    })
                    .option(ChannelOption.SO_BACKLOG, 128) // 设置连接队列大小
                    .childOption(ChannelOption.SO_KEEPALIVE, true); // 启用TCP KeepAlive

            // 绑定端口并启动服务器
            ChannelFuture channelFuture = serverBootstrap.bind(8092).sync();
            // 等待服务器关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            // 异常处理,抛出运行时异常
            throw new RuntimeException(e);
        } finally {
            // 关闭EventLoopGroup,释放资源
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}
2.4、对数据进行相应的处理发送到ThingsBoard客户端

mqtt的username是设备的ID,根据你们自己的设备ID进行修改

/**
 * 该类继承自SimpleChannelInboundHandler,用于处理设备数据。
 * 当设备数据到达时,会将数据发送到MQTT服务器。
 */
package com.example.tpson_tcp;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.eclipse.paho.client.mqttv3.IMqttClient;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;

public class DeviceDataHandler extends SimpleChannelInboundHandler<String> {

    private IMqttClient mqttClient; // MQTT客户端接口

    /**
     * 构造函数:初始化MQTT客户端并连接到服务器。
     */
    public DeviceDataHandler() {
        try {
            mqttClient = new MqttClient("tcp://127.0.0.1:1883", MqttClient.generateClientId());
            MqttConnectOptions options = new MqttConnectOptions();
            options.setCleanSession(true); // 设置会话清除标志
            options.setUserName("001001001"); // 设置用户名
            mqttClient.connect(options); // 连接到MQTT服务器
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 当通道中有可读数据时调用该方法。
     *
     * @param ctx 通道上下文
     * @param msg 接收到的消息
     * @throws Exception 抛出的异常
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("Received device data: " + msg);
        // 将接收到的设备数据发送到MQTT的主题
        MqttMessage message = new MqttMessage(msg.getBytes());
        System.out.println(message);
        mqttClient.publish("v1/devices/me/telemetry", message);
    }

    /**
     * 当捕获到异常时调用该方法。
     *
     * @param ctx 通道上下文
     * @param cause 异常原因
     * @throws Exception 抛出的异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close(); // 关闭通道
    }
}
2.5、通过TCP链接工具

链接到服务器:localhost,端口:8092上 

发送区发送数据:

{time:”2024年5月5日”}
 2.6、查看遥测数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607546.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【备战软考(嵌入式系统设计师)】11 - 硬件电路基础

逻辑门电路 首先我们需要先了解三个最基础的门电路&#xff0c;可以说我们一切的电子产品的基石就是这哥仨&#xff0c;它们就与&#xff0c;或&#xff0c;非。 与门和或门有两个输入端&#xff0c;一个输出端&#xff1b;非门有一个输入端一个输出端。 在我们数字电路中&a…

IOS Xcode证书配置和ipa打包流程(附详细图文教程)

IOS Xcode证书配置和ipa打包流程&#xff08;附图文教程&#xff09; 前言ipa文件简介证书文件简介Provisioning Profile描述文件简介当前环境版本Xcode证书配置和ipa打包流程生成Apple Distribution Certificates证书创建描述文件&#xff08;Provisioning Profiles&#xff0…

车载测试系列:车载以太网测试(一)

汽车行业对可靠性和安全性要求越来越高&#xff0c;车载以太网在应用过程中&#xff0c;为了保证其可靠性与安全性&#xff0c;需要对其开展测试工作。 传统的以太网测试和车载以太网测试存在一定差异&#xff0c;传统以太网测试方法并不适用汽车以太网测试。 汽车行业对测试…

代码随想录第四十三天|最后一块石头的重量 II 、目标和

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a; 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a;

986: 哈夫曼译码

解法&#xff1a;先把代码粘贴到编译器&#xff08;vs&#xff09;上&#xff0c;分享一个一键去除空白行的操作&#xff0c;ctrlf调出查找窗口&#xff0c;输入查找(?<\r\n)\r\n&#xff0c;选择正则表达式&#xff0c;替换就可以发现会去掉一百多行空白行。 本题只需要利…

通用型产品发布解决方案(基础环境搭建)

文章目录 1.项目技术栈和前置技术2.创建Linux平台1.需求分析2.安装Virtual Box1.BIOS里修改设置开启虚拟化设备支持&#xff08;f2 或f10&#xff09;2.任务管理器 -> cpu 查看虚拟化是否开启3.卸载方式4.安装6.1.265.管理员身份运行&#xff0c;选择安装位置6.一直下一步&a…

我的Transformer专栏来啦

五一节前吹的牛&#xff0c;五一期间没完成&#xff0c;今天忙里偷闲&#xff0c;给完成了。 那就是初步拟定了一个《Transformer最后一公里》的写作大纲。 之前一直想写一系列Transformer架构的算法解析文章&#xff0c;但因为一直在忙&#xff08;虽然不知道在忙啥&#xf…

银行职员向媒体投稿发文章我找到了好方法

作为一名基层银行的媒体联络专员,我的日常工作中有一项至关重要的任务,那就是代表我所在的支行向各大媒体投稿,传播我们的金融服务、产品动态以及社会责任实践。起初,这项看似简单的工作却成了我职业生涯中的一大挑战。传统的邮件投稿方式,不仅耗时费力,而且审核流程严格,稿件从…

【DSIN】深度 Session 兴趣网络

一、提出动机 这个模型依然是研究如何更好地从用户的历史行为中捕捉到用户的动态兴趣演化规律。 1.1、序列本身的特点&#xff1a; 其实用户点击序列有他自己本身的特点&#xff1a;用户过去可能有很多历史点击行为&#xff0c;按照用户的点击时间排好序&#xff0c;比如[it…

【Linux】yum与vim

文章目录 软件包管理器&#xff1a;yumLinux安装和卸载软件包Linux中的编辑器&#xff1a;vimvim下的底行模式vim下的正常模式vim下的替换模式vim下的视图模式vim下的多线程 软件包管理器&#xff1a;yum yum其实就是一个软件,也可以叫商店 和你手机上的应用商店或app store一…

【FreeRTOS 快速入门】-- 1、STM32工程移植FreeRTOS

目录 一、新建STM32工程 为了示范完整的移植过程&#xff0c;我们从0开始&#xff0c;新建一个标准的STM32点灯工程。 &#xff08;本篇以CubeMX作示范&#xff0c;CubeIDE操作近同&#xff0c;可作对比参考&#xff09; 1、新建工程 选择 芯片型号 新建工程 2、搜索芯片型号…

计算方法实验9:Romberg积分求解速度、位移

任务 输出质点的轨迹 ( x ( t ) , y ( t ) ) , t ∈ { 0.1 , 0.2 , 0.3 , . . . , 10 } (x(t), y(t)), t\in \{0.1, 0.2, 0.3, ..., 10\} (x(t),y(t)),t∈{0.1,0.2,0.3,...,10}&#xff0c;并在二维平面中画出该轨迹.请比较M分别取4, 8, 12, 16, 20 时&#xff0c;Romberg积分达…

MTK平台ATE tool

一、校准测试环境搭建 ① 仪器端一个端口直接连接功分器。 ② 功分器输出端外接3dbm的衰减器。 ③功分器空出来的端口需要外接50 Ω的负载。 ④功分器与手机端口的连接没有顺序之分。 二、ATE设置介绍 ATE所支持的无线通信系统 — GSM — WCDMA — TDSCDMA — LTE — WI…

Redis持久化策略——Java全栈知识(17)

Redis持久化 1、Redis 持久化的三种方式 1、RDB&#xff1a; 以快照的方式将此刻 Redis 中的数据以二进制的文件形式保存在磁盘中。 RDB 的优点是&#xff1a;快照文件小、恢复速度快&#xff0c;适合做备份和灾难恢复。 RDB 的缺点是&#xff1a;定期更新可能会丢数据&#…

2024年软件测试最全Jmeter--【作为测试你必须要知道的】基础名词与环境搭建,2024年最新年末阿里百度等大厂技术面试题汇总

网上学习资料一大堆&#xff0c;但如果学到的知识不成体系&#xff0c;遇到问题时只是浅尝辄止&#xff0c;不再深入研究&#xff0c;那么很难做到真正的技术提升。 需要这份系统化的资料的朋友&#xff0c;可以戳这里获取 一个人可以走的很快&#xff0c;但一群人才能走的更…

使用videosapi开发微信聊天记录防撤回

接口地址&#xff1a; http://接口地址/post/api/ 接收到消息后&#xff0c;如若进行撤回比较繁琐。 记录消息即可。 {"TypeName": "AddMsg", 回调消息类型"Appid": "wx_*_**_***", 设备appid"Wxid": "wxid_****…

从零学算法42

42.接雨水 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3…

短信公司_供应群发短信公司

短信公司——供应群发短信公司 短信公司作为一种为企业提供群发短信服务的服务商&#xff0c;正逐渐受到市场的青睐。供应群发短信公司作为其中的一种类型&#xff0c;为各行各业的企业提供高效、便捷的短信推广渠道。本文将介绍短信公司的作用以及供应群发短信公司的特点和优势…

基于springboot+mybatis+vue的项目实战之增删改查CRUD

目录结构 PeotController.java package com.example.controller;import com.example.pojo.Peot; import com.example.pojo.Result; import com.example.service.PeotService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web…

10大排序方法,其中这里只介绍前7种(第4种C语言,其它C++语言)

排序方法有十种&#xff0c;分别是&#xff1a;一、冒泡排序&#xff1b;二、选择排序&#xff1b;三、插入排序&#xff1b;四、希尔排序&#xff1b;五、归并排序&#xff1b;六、快速排序&#xff1b;七、堆排序&#xff1b;八、计数排序&#xff1b;九、桶排序&#xff1b;…