RK3588这块板子拿到手还没捂热,我们极物科技这边就给它定了第一个正经任务:在Ubuntu 20.04系统下,把它和ThingsBoard平台之间的三条数据通道全部实测一遍。你没看错,不是先跑yolov8做图像识别,而是先解决"数据怎么出去"这个问题。因为不管板子上AI推理跑得多溜,算出来的结果上不了云、平台侧收不到,一切都白搭。
这篇文就是我完整记录下来的连通性测试过程,覆盖MQTT、HTTP、COAP三种与ThingsBoard对接的常规协议。内容包括我的环境准备、每条链路的实测命令与返回结果、测试中踩过的坑,以及最终的数据对比和网关场景选型建议。适合RK3588开发板的玩家、ThingsBoard新用户、做设备接入网关的嵌入式工程师参考,哪怕你之前没接触过物联网平台,按我这份流程也能把设备接进去。
1. 为什么要先把RK3588和ThingsBoard的链路跑通
很多人在拿到RK3588这种级别的开发板时,第一反应是刷个镜像、跑个AI Demo,看看那4个Cortex-A76大核到底多能打。这个思路没错,但在实际项目里,设备不能只待在实验室里跑推理,它得把数据交出去给平台侧消费。我们当时接到一个边缘计算网关的需求,板子上要跑目标检测模型,又要定时上报设备状态。既然平台定的是ThingsBoard,那MQTT、HTTP、COAP这三条腿,就必须在开发阶段先挨个走一遍。
1.1 RK3588在物联网平台接入里的定位
RK3588是瑞芯微的旗舰级SoC,8核心设计(4个A76大核+4个A55小核),aarch64架构,有独立的NPU,跑yolov8这类模型很从容。但要注意,这套组合的定位和普通的MCU级物联网终端完全不一样:MCU通常就是采集传感器、定时上报,数据量小、功耗要求苛刻;而RK3588更像是一个边缘服务器,它既要承担推理计算,又要作为网关汇聚下挂设备的数据,然后把数据统一上送。
这就意味着它的接入方式不能太"玩具"。你很难靠一条串口线把推理结果传到机房,需要的是一个工业级的物联网接入协议,要支持断线重连、要带消息确认、要考虑带宽占用。而ThingsBoard恰恰是主流的开源物联网平台之一,它把这些协议做了统一封装,后端不用管设备具体用的是MQTT还是COAP,只管消费数据就行。所以在RK3588上验证与ThingsBoard的连通性,本质上是验证"算力节点"和"平台"之间的运输线通不通。
1.2 三协议在网络选型中的角色
大家常说的"三协议",在物联网场景里分工非常明确:
- MQTT:基于TCP的发布/订阅协议,长连接、低开销、有QoS分级。适合频繁、持续、双向的数据交互。RK3588到ThingsBoard的主数据通道基本就是它。
- HTTP:典型的请求/响应模式,无状态,实现最简单。适合低频的遥测上报、设备注册、告警通知。很多设备只要求定时打个REST接口,那就不必上MQTT。
- COAP:基于UDP的轻量协议,面向资源,类似"HTTP over UDP"。报文头特别小,适合窄带宽、弱网环境下的受限设备。
ThingsBoard默认三种协议都支持,所以在一条RK3588上把它们全测试一遍,等于验证了平台对不同设备群体的兼容性。如果你以后接了旧设备,它只支持COAP,你心里也有底,知道平台侧怎么应对。
1.3 这次测试的边界:只验证上行遥测
为了不让测试范围发散,我先声明一下边界:这次连通性测试只做设备到平台的上行遥测数据,也就是把JSON格式的遥测数据通过三种协议发到ThingsBoard,然后在平台侧看数据是否成功入库。不涉及RPC反向控制、不涉及设备属性共享、也不做批量告警。先把最简单、最核心的"数据能否上去"跑通,再谈别的。
2. 测试环境准备:RK3588、ThingsBoard实例和三个命令行工具
连通性测试听起来简单,但环境没准备干净,后面排查问题会非常痛苦。我按三个部分说:RK3588系统侧、ThingsBoard平台侧、以及测试工具侧。
2.1 RK3588这边的系统准备
我手上这块RK3588开发板刷的是Ubuntu 20.04镜像,注意确认是aarch64版本,不是x86的移植版,否则后面的apt源和Python包都会出问题。刷完系统后第一件事不是装东西,而是确认网络:
uname -a # Linux rk3588 5.10.xxx #1 SMP ... aarch64 aarch64 aarch64 GNU/Linux ip addr show eth0 ping -c 4 10.0.0.1这里有一个容易被忽略的点:RK3588开发板有的网口默认没启用DHCP,得手动配置静态IP。我们当时用串口登录后配置了/etc/netplan/01-network-config.yaml,改完执行sudo netplan apply才拿到IP。
系统侧还要准备SSH,方便后续传脚本和命令。sudo apt install openssh-server,确认22端口监听后,我后续的测试都是在SSH会话里进行的,因为开发板一般不方便直接接显示器键盘。
2.2 ThingsBoard侧准备:端口、设备Profile和Access Token
ThingsBoard这边我用了两个方式:一个是用官方Docker镜像在局域网服务器上自建实例,另一个是直接连ThingsBoard云版。自建实例的好处是端口随意控制,测试失败可以抓包。云版的好处是免运维。
自建命令参考如下:
docker run -d --name my-tb \ -p 8080:9090 \ -p 1883:1883 \ -p 5683:5683/udp \ thingsboard/tb-postgres注意这里的关键点:容器里ThingsBoard WEB UI端口是9090,我用-p 8080:9090把它映射到宿主的8080;MQTT端口1883;COAP端口5683是UDP。HTTP的REST API端口和WEB UI一样是9090,被映射到8080。所以后续我命令里的地址是http://192.168.x.x:8080,而非9090,这就是端口映射带来的坑,后面细说。
登录ThingsBoard后,在"实体 -> 设备"页面创建一个设备,名字随意比如"rk3588-gateway"。创建完成后打开设备详情,里面有一串Access Token,它是一个UUID样式的字符串。这串Token就是之后三种协议接入时的凭据,相当于设备的"身份证号"。我强烈建议把它保存成一个环境变量:
export ACCESS_TOKEN="你的设备令牌"另外检查一下设备Profile(设备配置文件)里有没有把HTTP、MQTT、COAP三个Transport都勾选启动。新版ThingsBoard默认是开启的,但如果你用的是定制过的旧版本或者Docker镜像配置裁剪过,就需要手动确认。这是很多"平台怎么连不上"问题的根源。
2.3 安装测试工具:mosquitto-clients、curl、libcoap
测试工具我特意选了命令行工具,因为脚本化方便、输出直观、依赖少。在RK3588上直接apt安装:
sudo apt update sudo apt install -y mosquitto-clients curl libcoap3-binmosquitto-clients提供mosquitto_pub和mosquitto_sub,用来测MQTT发布订阅。curl用来测HTTP REST API。libcoap3-bin提供coap-client,用来测COAP。
另外我还装了一个Python的paho-mqtt库,因为后面要做持续批量测试,命令行工具更适合验证单条消息,而脚本可以测长时间稳定性:
sudo apt install -y python3-pip pip3 install paho-mqtt工具装好后,先确认一下版本,避免后面出现命令不兼容的情况:
mosquitto_pub -h coap-client -h curl --version三个工具都正常输出版本信息,环境准备就算完成了。
3. MQTT协议连通性测试:主推通道的完整实测
先把MQTT这条最重要的通道打通。整个测试我分了三步:搞清ThingsBoard的MQTT接入逻辑,用mosquitto_pub验证单条消息,再用paho-mqtt脚本做批量稳定性测试。
3.1 ThingsBoard对MQTT的接入逻辑:Access Token就是用户名
ThingsBoard的MQTT接入不需要用户名密码,而是将设备的Access Token写入用户名,密码可为空。MQTT主题分三类:遥测数据发到v1/devices/me/telemetry,属性数据发到v1/devices/me/attributes,RPC请求发到v1/devices/me/rpc/request/+。
我们这次只测遥测。一个最简MQTT接入配置如下:
mosquitto_pub -d \ -h 192.168.x.x \ -p 1883 \ -u "$ACCESS_TOKEN" \ -t "v1/devices/me/telemetry" \ -m '{"temperature": 25.5, "humidity": 60}'-t后面的主题是ThingsBoard定死的,不能自己发明。-m后面必须是一段合法的JSON字符串,单个遥测数据可以是一条JSON、也可以是JSON数组。-u后面就是Access Token。执行后,-d参数会输出完整的MQTT报文交互:
Client mosq-xxxx sending CONNECT Client mosq-xxxx received CONNACK Client mosq-xxxx sending PUBLISH Client mosq-xxxx received PUBACK看到CONNACK说明鉴权成功,PUBACK说明消息已被平台接收。ThingsBoard收到遥测数据后,在设备详情页"最新遥测"标签下,就会出现temperature和humidity两个字段。我就是在这里确认数据确实落库的。
3.2 用paho-mqtt在RK3588上做1000条数据的持续测试
命令行验证单条消息只能说明链路是通的,不能说明链路是稳的。为了模拟实际网关的持续上报,我写了个Python脚本,在RK3588上循环发送1000条遥测数据:
import paho.mqtt.client as mqtt import time import json import random ACCESS_TOKEN = "DEVICE_ACCESS_TOKEN" BROKER_HOST = "192.168.x.x" BROKER_PORT = 1883 TOPIC = "v1/devices/me/telemetry" client = mqtt.Client(client_id="rk3588-gateway-test") client.username_pw_set(ACCESS_TOKEN, None) client.connect(BROKER_HOST, BROKER_PORT, keepalive=60) for i in range(1000): payload = { "seq": i, "temperature": round(random.uniform(20.0, 30.0), 2), "cpu_load": round(random.uniform(0.2, 0.9), 2) } result = client.publish(TOPIC, json.dumps(payload), qos=1) if result.rc != mqtt.MQTT_ERR_SUCCESS: print(f"Publish failed at seq={i}: rc={result.rc}") if i % 100 == 0: print(f"Published {i}/1000") time.sleep(0.05) client.disconnect()这段脚本最核心的是qos=1。QoS=1要求平台确认收到消息才返回,少了这一级,你很难判断是网络丢包还是平台没收到。1000条跑完,我做了两件事:看终端是否出现所有发布成功的输出,然后在ThingsBoard的遥测详情页里检查seq的最大值是否到了999。
当时的结果:1000条全部成功,遥测列表里seq从0到999都有,丢包率为0。局域网内的MQTT稳定性,就是这么扎实。
3.3 MQTT测试中我踩过的三个坑
一路顺利是不可能的,我把这次MQTT测试里踩过、后来也多次在群里看到别人踩的坑列出来:
- 端口映射遗漏。Docker自建ThingsBoard时,只映射了8080端口,漏了1883的MQTT端口,结果平台WEB界面正常,MQTT就是连不上。用
docker port my-tb检查一下映射关系即可。 - Access Token没生效就急着发。在ThingsBoard里修改设备凭据后,MQTT Broker侧需要一点时间同步,或者你压根忘了保存。最简单的验证是把Token抄到mqttx这种客户端里连一次,连不上就直接检查Token和网络。
- 消息体不是合法JSON。ThingsBoard对遥测数据的格式要求很严格,你发送
'temperature:25.5'这种非JSON字符串,Broker会直接断开连接或者返回错误。发之前用python3 -c "import json; json.loads('...')"校验一下最稳。
4. HTTP REST接口:一条只用curl就能验证的线路
MQTT是主通道,但HTTP在物联网项目里同样有它的位置——低频采集、告警通知、设备启动时的注册信息。ThingsBoard的HTTP接口走REST风格,实现逻辑和MQTT完全不同,这节我来拆解。
4.1 ThingsBoard REST API的鉴权和URL设计
ThingsBoard对设备接入HTTP的方式很直接:设备把Access Token直接拼在URL里,以/api/v1/{ACCESS_TOKEN}/telemetry的形式调用POST接口。
注意这个和平台管理员调REST API的鉴权方式完全不同,管理员用的是一长串JWT Token通过X-Authorization: Bearer <token>请求头传输,而设备接入用的是URL嵌Token。如果你搞混了,会出现"管理员接口通了、设备接口却401"的情况。
curl -v \ -X POST \ -H "Content-Type: application/json" \ -d '{"temperature": 23.8, "humidity": 55}' \ http://192.168.x.x:8080/api/v1/$ACCESS_TOKEN/telemetry执行后,-v会输出整个交互过程。关键要看两个地方:HTTP状态码和响应时间。正常返回HTTP/1.1 200 OK,响应体为空——ThingsBoard设计就是这样,200代表平台已接收遥测,但不会回显收到的数据,验证要靠平台侧查询。
4.2 响应码解读:200、400、401分别说明什么问题
HTTP测试过程中,响应码就是最直接的诊断工具。我整理的对照表:
| 状态码 | 含义 | 原因处理 |
|---|---|---|
| 200 | 接收成功 | 数据已写入平台,去设备遥测页确认 |
| 400 | 请求格式非法 | JSON格式错误或缺少必要字段,检查-d参数 |
| 401 | 鉴权失败 | Access Token错误、过期或设备未启用HTTP传输 |
| 404 | 接口路径错误 | 检查URL路径是否写错,特别是api/v1这个前缀 |
| 408 | 请求超时 | 局域网延迟高或平台负载大,需要看网络链路 |
我实测时还遇到过一种情况:ThingsBoard容器所在机器防火墙封了8080端口,场景表现为浏览器能打开ThingsBoard登录页、curl却一直超时。后来发现是防火墙规则只放行了容器内部的9090,外部8080断了,但登录页是通过别的链路缓存的。所以HTTP测试前建议先curl -I一下平台根路径,确认服务真的可达。
RouteKey note:还有一个不起眼但挺坑的点,URL中的Token如果含有特殊字符要URL编码,不过ThingsBoard生成的Token通常只是字母数字加短横线,实际项目中我还没遇到需要转义的场景。
4.3 HTTP链路的适用范围:为什么有MQTT了还得留条REST通道
有人会问,既然MQTT能做长连接低延迟推送,为什么很多网关项目还保留HTTP上报?我的实际经验是:HTTP在低频、偶发、消息量小的场景下性价比极高。
举个例子,温度异常告警,一天可能就触发一两次,你用MQTT维持长连接每分钟消耗一个心跳包,反而不经济。用HTTP定时POST一条JSON,服务器和客户端都不用维持复杂连接状态,出了问题调试也更简单。所以在RK3588网关里,我通常设计成:周期性长时间数据走MQTT,瞬时紧急告警走HTTP兜底。
5. COAP链路测试:UDP轻协议不是拿来就能用的
MQTT和HTTP都属于TCP系协议,而COAP是UDP之上的一层轻协议,设计目标是为资源受限的设备服务。在RK3588这种"性能过剩"的平台上测COAP,多少有点大材小用,但为了兼容老设备、验证平台能力,这一步还得做。
5.1 搞清楚COAP的接入前提
COAP是UDP协议,默认端口5683,在ThingsBoard里设备上报的接入路径是coap://<host>:5683/api/v1/<ACCESS_TOKEN>/telemetry。
与MQTT和HTTP最大的不同在于:COAP消息本身不保证送达。UDP没有TCP的确认重传机制,需要COAP协议栈自己处理CON(需确认消息)和ACK(确认应答)。所以在ThingsBoard侧配置COAP传输时,要确认设备是发CON消息还是NON消息,这决定了平台收到消息后会不会回ACK。
我在测试前特意确认了ThingsBoard的设备Profile里COAP Transport是打开的,并且用的是CON模式——这样才能在日志里看到确认机制,万一线程出错也更容易定位。
5.2 用coap-client发送遥测数据
libcoap提供的coap-client命令行工具,用法和curl有点像:
coap-client \ -m post \ coap://192.168.x.x:5683/api/v1/$ACCESS_TOKEN/telemetry \ -c '{"temperature": 21.3, "device_status": "online"}' \ -v 9参数解释:
-m post:指定请求方法是POST。-c:后面跟要发送的payload内容,注意这里是-c(content),不是curl的-d。-v 9:把调试日志级别拉到最高,方便看UDP交互过程。
输出里能看到类似这样的信息:
if_get_request: start request Sending CoAP request: UDP: 192.168.x.x:5683 CoAP version: 1 Type: CON Code: POST Token: 0x12345678 Options: Uri-Path: "api" Uri-Path: "v1" Uri-Path: "DEVICE_ACCESS_TOKEN" Uri-Path: "telemetry"这行输出最大的价值在于,它明明白白告诉你:COAP请求是通过UDP发出去的、消息类型是CON、token是多少。在返回中如果看到Code: 2.01 Created之类的应答,说明平台已接收遥测。
要注意的一点是,coap-client通过-c传参时,-c后面若是-表示从标准输入读取内容,但直接写JSON字符串在部分版本上会正常解析,不过有时需要加-f参数指定文件名或借助管道。遇到读不到payload的情况,改成-f -再结合管道输入即可。我这次测试直接传字符串是没问题的,但这个细节在脚本化批量发送时经常坑人。
5.3 COAP限流与重试机制:别用TCP的思维去理解UDP
COAP测试里最容易被忽视的是"限流重试"。我尝试一次性连发500条,结果发现有一批消息丢了——不是ThingsBoard拒绝,而是UDP根本不管丢包,发送端发完就完事了。
这种特性在资源受限的传感器里是可接受的,但在RK3588网关汇聚数据的场景里,就要求上层业务自己负责可靠传输。于是我改了策略,用Python的aiocoap库实现"CON模式+重传":
import asyncio import aiocoap async def send_coap(host, port, token, payload): context = await aiocoap.Context.create_client_context() request = aiocoap.Message( code=aiocoap.POST, uri=f"coap://{host}:{port}/api/v1/{token}/telemetry", payload=payload.encode("utf-8") ) response = await context.request(request).response print("Response code:", response.code) asyncio.run(send_coap("192.168.x.x", 5683, "DEVICE_ACCESS_TOKEN", '{"temp": 1}'))跑下来的结果还算理想,CON模式下每条消息都能拿到响应。所以结论很明确:COAP不是不能用于RK3588网关,而是你必须自己构建可靠传输层。
6. 三协议实测汇总与网关场景下的选型思路
三条协议都跑通之后,我做了一次横向对比,把同一份1000条遥测数据分别用MQTT、HTTP、COAP发一遍,记录实测情况(局域网内、RK3588作为发送端、Docker部署的ThingsBoard作为接收端)。
6.1 实测数据对比
以下数据仅为我在当前测试环境下的观察结果,供参考,不是实验室级精确测试,但趋势肯定是准的:
| 协议 | 耗时(1000条) | 丢包/失败率 | 消息平均大小 | 实现复杂度 | 适用场景 |
|---|---|---|---|---|---|
| MQTT (QoS1) | 45秒左右 | 0% | 约80字节(含Topic与消息头) | 低 | 持续高频上报、长连接双向通信 |
| HTTP | 80秒左右 | 0%(失败会立即暴露) | 约120字节(含HTTP头) | 最低 | 低频上报、临时告警、状态查询 |
| COAP (CON) | 55秒左右 | 约1%需重传 | 约50字节 | 中(需自己处理重传) | 弱网、窄带宽、资源受限设备 |
这个表格透露出两个关键信息:MQTT在吞吐量和可靠性上完胜,是RK3588这类高性能网关的头号选择;COAP消息最小,在窄带弱网环境有不可替代的价值;HTTP没有优势但在集成调试时最方便——很多网关的出厂自检用HTTP就能完成,不需要一套完整的MQTT客户端。
6.2 结合边缘AI场景的选型建议
回到我们极物科技的RK3588项目里,实际方案是这样的:
- AI推理结果(识别框、置信度、时段统计):走MQTT主题
v1/devices/me/telemetry,用QoS1保证批量数据不丢。 - 设备心跳、启动日志、固件版本信息:走MQTT的
v1/devices/me/attributes,这类数据不需要高频更新,平台侧好归类。 - 紧急告警(比如推理进程挂掉、NPU过热):走HTTP REST接口,一条POST带完内容。
- 下挂的电池类传感器节点:走COAP,它们本身的MCU算力有限,COAP对它们最友好。
顺带说一句,搜索热词里也有KingsCADA这类SCADA系统如何获取MQTT数据。实际上,ThingsBoard本身可以配置规则引擎把MQTT数据转发给Kafka或直接通过REST API向外推送,SCADA这类工业组态系统再消费转发下来的数据。这意味着RK3588网关接入ThingsBoard后,数据还可以继续往上层工控系统流,链路的可靠性就更加重要了。
6.3 RK3588实测中值得注意的几个细节
整个测试过程下来,我整理了几个在RK3588上特别容易遇到的问题:
- Ubuntu 20.04的ARM源可能比较旧。mosquitto-clients版本偏老,个别参数如
--url在旧版上不可用,用-h、-p更兼容。如果apt源的包版本太老,可以从源码编译mosquitto或直接用Python paho库代替。 - RK3588的网卡一定要先确认速率协商。这块板子的网卡有多个速率档位,如果网线质量不好会自动降速到100M甚至10M,在1000条消息测试时会出现毛刺延迟。用
ethtool eth0检查一下当前速率很必要。 - When using Docker部署ThingsBoard,容器时间要和服务器保持一致。遥测数据如果带时间戳,容器和宿主机时间偏差过大会导致数据显示异常,虽然这不影响协议连通,但会让你误以为数据没传成功。
最后再分享一条个人经验
这套三协议连通性测试做完,我心里对RK3588网关的接入方案总算有了底气。个人体会是:协议测试不能只看"通不通",要看"通得稳不稳"。MQTT在局域网里1000条零丢包,但到了公网、跨运营商环境下,心跳参数、QoS级别、keepalive间隔都要重新调。我的做法是把这套测试脚本保存下来,每次网络环境变更后都跑一遍,效率极高。
下一步我准备测试ThingsBoard的RPC反向控制链路,让云端能远程下发命令给RK3588,比如重启算法进程、切换推理模型。到那时再写一篇RPC和属性的实战记录。如果你也在调RK3588接ThingsBoard,照着文中的流程走一遍,任何一步不通,欢迎带着你的错误输出过来交流,我们极物科技踩过的坑,你大概率能避开。