ThingsBoard 自定义 TCP Transport
正文与配图来自原稿。CE 无 PE Integration 那种现成 TCP 长连接接入时,可按 MQTT Transport 结构自研 tcp-transport,支持上报与 RPC。
1、概述
现场大量设备用 TCP / MQTT 连平台。ThingsBoard PE 可用 Integration 做 TCP;CE 没有同等能力,需要自定义 Transport:长连接、自定义编解码、上报遥测、接收 RPC。
Transport 公共逻辑在 common/transport,启动类在 transport / application 侧,需按官方模块规则接入。
2、创建 tcp 模块
2.1、描述
仿 MQTT:在 common/transport 下建 tcp 子模块,再在依赖与配置中打开。
2.2、common 下创建模块
打开 transport 下已有模块:

选中 transport → New → Module:

按图配置:

创建结果:

父 POM 增加 tcp 子模块:

拷贝 mqtt 模块 pom 到 tcp,把 artifactId 改为 tcp:



在 src/main/java 建包 org.thingsboard.server.transport.tcp:

codec / protocol 可省略,session 必须有:

坑: IDEA 模块显示名可能与 mqtt 不一致。对模块 Refactor → Rename → Rename module,改成类似:
tcp (org.thingsboard.common.transport)




依赖可直接参考 mqtt(transport-api、netty-all 等):

包结构再次确认:

关键类(与 MQTT 对齐)
| 类 | 作用 |
|---|---|
| TcpTransportContext | 继承 TransportContext,条件装配 transport.tcp.enabled |
| TcpTransportService | Netty ServerBootstrap 绑定 transport.tcp.bind_address/port |
| TcpTransportServerInitializer | pipeline:编解码 + Handler |
| TcpTransportHandler | 实现 SessionMsgListener,处理上行 JSON 与下行 RPC |
| TcpDeviceSessionCtx | 继承 DeviceAwareSessionContext,会话上下文 |
条件注解示例(与原稿一致):
@ConditionalOnExpression(
"'${service.type:null}'=='tb-transport' || "
+ "('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true' "
+ "&& '${transport.tcp.enabled}'=='true')"
)TcpTransportService 用 Netty 监听配置端口,childHandler(new TcpTransportServerInitializer(context))。
Handler 内按 JSON 字段 serviceName 分支(原稿示例协议):
login → {"serviceName":"login","sign":"123","data":{"token":"<ACCESS_TOKEN>"}}
heartbeat → {"serviceName":"heartbeat","sign":"123","data":{"heartbeat":"ping"}}
inPark → {"serviceName":"inPark","sign":"123","data":{"carNumber":"川A123456"}}
outPark → …登录用 Token 建会话;业务报文转遥测上报;onToDeviceRpcRequest 里编码后经 TCP 写回设备。
2.3、transport 启动工程
在 transport 侧建 tcp 启动相关工程/配置(对照 mqtt-transport):





yml 中增加 transport.tcp(bind、netty 线程、enabled 等),写法可抄 transport.mqtt 段:

2.4~2.6、POM 依赖三处
根 POM:
<dependency>
<groupId>org.thingsboard.common.transport</groupId>
<artifactId>tcp</artifactId>
<version>${project.version}</version>
</dependency>
application 模块:
<dependency>
<groupId>org.thingsboard.common.transport</groupId>
<artifactId>tcp</artifactId>
</dependency>
tcp 启动工程 pom:

3、测试
TCP 工具连 TB 的 TCP 端口:

平台创建设备,记下 Token:

发送登录:
{"serviceName":"login","sign":"123","data":{"token":"<你的设备Token>"}}
登录成功提示:

设备页显示在线:

上报业务(示例停车):
{"serviceName":"inPark","sign":"123","data":{"carNumber":"川A123456"}}遥测可见车牌等字段:

平台下发 RPC 后,在 onToDeviceRpcRequest 收到并写出:


4、核心小结
核心是 TcpTransportHandler 实现 SessionMsgListener:上行自定义解码进 TB,下行 RPC 自定义编码经 Channel 写出。
必做三步:
common/transport定义 tcp 模块

- 根 POM 声明依赖

- application(及启动工程)引入依赖

其余对照 mqtt 模块改即可。
补充(辅)
- 完整类代码以原稿/你仓库为准;本文抓结构与联调协议。
- 打开
transport.tcp.enabled=true并配置端口,避免与 MQTT1883冲突。 - 对照:MQTT Transport 源码分析。
