# matrix-iot **Repository Path**: sk_apt/matrix-iot ## Basic Information - **Project Name**: matrix-iot - **Description**: Matrix-IoT 是一个面向物联网设备的轻量级网关服务框架,提供多种协议(TCP、UDP、CoAP、MQTT)的设备接入能力,支持分布式部署和水平扩展。基于 Matrix-IoT可以快速搭建高并发、高可用的物联网设备接入平台。 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2026-04-09 - **Last Updated**: 2026-06-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README
Matrix-IoT
## 简介 `Matrix-IoT`是一个面向物联网设备的轻量级网关服务框架,提供多种协议(TCP、UDP、CoAP、MQTT)的设备接入能力,支持分布式部署和水平扩展。基于 `Matrix-IoT`可以快速搭建高并发、高可用的物联网设备接入平台。 ## 发展历程 - 2019年Java微服务完整版`Matrix-IoT`开发完成 - 至2021年经过智能家居、车联网等项目锤炼和优化迭代,逐步形成成熟产品,被广泛应用于物联网设备接入场景。 - 2023年根据实际项目要求,Go微服务完整版开发完成,双版本并行、按需实施。 - 目前开源的是`Matrix-IoT`(Go设备接入服务)后端核心功能框架,带来更优越的性能和可扩展性。(剥离具体业务仅保留核心功能框架) ## 关于Matrix-IoT - ✅**寓意**:Matrix(矩阵),象征连接万物的网络,构建物联网设备的互联互通 - ✅**理念**:开放、高效、可靠、可扩展 - ✅**原则**:最小依赖可运行;模块化设计;贴近物联网场景只做有用的功能 *** ## 整体架构 ```mermaid flowchart TD subgraph 客户端 TCP[TCP设备] UDP[UDP设备] CoAP[CoAP设备] MQTT[MQTT设备] end subgraph 协议层 TCPServer[TCPServer\n消息解析 / 连接管理] UDPServer[UDPServer\n消息解析 / 连接管理] CoAPServer[CoAPServer\n消息解析 / 连接管理] MQTTServer[MQTTServer\n消息解析 / 连接管理] end subgraph 网关层 Gateway[Gateway] subgraph 消息处理器 Auth[认证校验] Forward[协议转发] end subgraph 连接管理器 Session[会话管理] Sync[分布式同步] end subgraph 订阅管理器 Subscribe[主题订阅] Route[消息路由] end end subgraph 中间件 MySQL[(MySQL\n设备信息存储)] Redis[(Redis\n分布式会话存储)] ConnInfo[(连接信息)] SubInfo[(订阅信息)] Queue[(消息队列)] end TCP --> TCPServer UDP --> UDPServer CoAP --> CoAPServer MQTT --> MQTTServer TCPServer --> Gateway UDPServer --> Gateway CoAPServer --> Gateway MQTTServer --> Gateway Gateway --> Auth Gateway --> Session Gateway --> Subscribe Auth --> Forward Session --> Sync Subscribe --> Route Gateway --> MySQL Gateway --> Redis Redis --> ConnInfo Redis --> SubInfo Redis --> Queue ``` **架构说明:** | 层级 | 职责说明 | |---------|---------------------------------------------| | **客户端** | 支持 TCP、UDP、CoAP、MQTT 四种协议的设备接入,负责设备与网关的网络通信 | | **协议层** | 各协议服务器负责消息解析、连接管理和协议适配,将不同协议消息转换为统一格式 | | **网关层** | 核心业务逻辑层,包含消息处理、认证校验、连接管理、订阅发布、分布式消息路由等核心功能 | | **中间件** | MySQL 负责设备信息存储,Redis 负责分布式会话存储、订阅信息管理和消息队列 | *** ## 核心技术栈 | 分类 | 技术 | 版本 | 用途 | |------------|------------------|-------|---------------------------------| | **语言** | Go | 1.21+ | 核心开发语言,高性能并发支持 | | **HTTP框架** | Gin | 1.9+ | RESTful API 服务框架 | | **关系型数据库** | MySQL | 8.0+ | 设备信息、配置数据持久化存储 | | **分布式缓存** | Redis | 7.0+ | 分布式会话存储、消息队列、订阅管理 | | **日志系统** | Zap + Lumberjack | - | 高性能结构化日志,支持日志轮转 | | **CoAP协议** | go-coap | 1.8+ | CoAP 协议解析和服务端实现 | | **MQTT协议** | 自研实现 | - | MQTT 3.1.1/5.0 协议支持,含 QoS 0/1/2 | ### 技术特性 - **高性能**:基于 Go 协程模型,支持百万级并发连接 - **分布式架构**:通过 Redis 实现分布式会话管理和消息路由 - **模块化设计**:协议层与业务层解耦,易于扩展新协议 - **可观测性**:内置监控指标、健康检查、日志追踪,支持分布式节点聚合统计 - **安全性**:支持 TLS/DTLS 加密传输、双向认证(mTLS) - **协议桥接**:支持 MQTT 与 CoAP 协议互转,实现跨协议通信 - **插件系统**:支持插件化扩展,动态加载功能模块 - **设备影子**:设备状态虚拟表示,支持离线命令缓存与状态同步 *** ## 核心功能 ### 一、多协议设备接入 | 协议 | 版本支持 | 核心特性 | |----------|-------------|---------------------------| | **TCP** | - | 长连接、心跳保活、TLS支持 | | **UDP** | - | 无连接、低延迟、组播支持、DTLS支持 | | **CoAP** | RFC 7252 | RESTful API、观察机制、DTLS支持 | | **MQTT** | 3.1.1 / 5.0 | QoS 0/1/2、主题订阅、保留消息、TLS支持 | **协议特性**: - 模块化设计,协议层与业务层解耦 - 统一消息格式,便于跨协议消息转发 - 支持协议扩展,易于添加新协议 ### 二、分布式架构 | 功能 | 实现方式 | 特性 | |----------|----------------------|-------------| | **会话管理** | Redis + 分片锁 | 支持百万级并发连接 | | **消息路由** | Redis Stream + 一致性哈希 | 分布式消息发布/订阅 | | **节点发现** | Redis 心跳检测 | 自动节点感知与负载均衡 | | **订阅同步** | Redis Pub/Sub | 跨节点订阅信息同步 | **部署模式**: - **单机模式**:适合最小化部署,无任何外部依赖、开箱即用,数据持久化可选内存模式或MySQL数据库或自行扩展 - **分布式模式**:支持水平扩展,通过 Redis 实现状态同步 ### 三、设备管理 | 功能 | 说明 | |----------|--------------| | **设备认证** | 支持密钥验证 | | **连接管理** | 连接建立、保活、断开处理 | | **状态监控** | 实时监控设备在线状态 | | **信息存储** | 设备信息持久化 | ### 四、消息持久化 | 功能 | 说明 | |-----------|---------------------| | **离线消息** | 设备离线时消息存储,上线后推送 | | **QoS保障** | MQTT QoS 1/2 消息重传机制 | | **消息存储** | Redis 存储,支持过期清理 | ### 五、设备影子 | 功能 | 说明 | 实现方式 | |----------|-----------------|------------| | **状态同步** | 设备上报状态与期望状态同步 | 内存/Redis存储 | | **离线命令** | 设备离线时缓存命令,上线后执行 | 队列缓存,上线触发 | | **状态查询** | 支持查询设备当前状态 | REST API | ### 六、安全增强 | 功能 | 说明 | |--------------|----------------------------------| | **TLS/DTLS** | TCP/MQTT 支持 TLS,UDP/CoAP 支持 DTLS | | **双向认证** | 配置 CA 证书后自动启用 mTLS | | **证书管理** | 支持证书加载、密钥文件配置 | ### 七、监控与运维 | 功能 | 说明 | |----------|--------------| | **连接统计** | 实时连接数、协议分布统计 | | **消息统计** | 消息收发数量、协议分布 | | **错误统计** | 错误率、异常监控 | | **流量统计** | 进出流量统计 | | **健康检查** | 服务健康状态检查接口 | *** ## 核心功能接口 ### 一、设备管理 提供设备的增删改查功能,支持设备信息的持久化存储。 **API 接口** | 接口 | 方法 | 说明 | |----------------|--------|------------------| | `/device` | POST | 创建设备 | | `/device` | PUT | 更新设备信息 | | `/device/:id` | GET | 根据ID获取设备信息 | | `/device/:id` | DELETE | 删除设备 | | `/device/list` | GET | 设备列表(支持条件过滤) | | `/device/page` | GET | 分页查询设备列表(支持条件过滤) | **请求参数示例** **创建设备** ```json { "name": "传感器设备", "serialNumber": "TEST0000000000001", "typeId": 1, "status": 1, "groupId": 1, "tagIds": "1,2,3", "tenantId": 1 } ``` **响应示例** ```json { "code": 200, "message": "success", "data": { "id": 1, "name": "传感器设备", "serialNumber": "TEST0000000000001", "typeId": 1, "status": 1, "groupId": 1, "tagIds": "1,2,3", "tenantId": 1, "createdAt": "2024-01-01 12:00:00", "updatedAt": "2024-01-01 12:00:00" } } ``` ### 二、密钥管理 提供设备密钥的生成和验证功能,用于设备认证。 **API 接口** | 接口 | 方法 | 说明 | |------------------|------|------------------| | `/secret` | POST | 根据设备序列号和加密类型生成密钥 | | `/secret/verify` | POST | 验证密钥有效性 | **请求参数示例** **生成密钥** ```json { "serialNumber": "TEST0000000000001", "cipherType": "aes256" } ``` **响应示例** ```json { "code": 200, "message": "success", "data": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=" } ``` ### 三、会话管理 提供设备连接管理和消息发布功能,支持分布式场景下的消息路由。 **API 接口** | 接口 | 方法 | 说明 | |-------------------------------------------|------|-------------| | `/session/connections/count` | GET | 获取当前连接数量 | | `/session/connections` | GET | 获取所有连接列表 | | `/session/connections/protocol/:protocol` | GET | 根据协议类型获取连接 | | `/session/connection/id/:id` | GET | 根据连接ID获取连接 | | `/session/connection/serial/:serial` | GET | 根据设备序列号获取连接 | | `/session/publish` | POST | 向指定设备发布消息 | **请求参数示例** **发布消息** ```json { "serialNumber": "TEST0000000000001", "protocol": "coap", "message": { "command": "turn_on_light" } } ``` **响应示例** ```json { "code": 200, "message": "success", "data": null } ``` ### 四、监控管理 提供服务运行状态监控,包括连接数、消息数、错误率、流量统计、协议桥接、插件状态、认证成功率等指标,支持分布式场景下的节点聚合统计。 **API 接口** | 接口 | 方法 | 说明 | |---------------------------|-----|-------------| | `/metrics` | GET | 获取完整监控指标汇总 | | `/metrics/connections` | GET | 获取连接数统计 | | `/metrics/messages` | GET | 获取消息收发统计 | | `/metrics/errors` | GET | 获取错误发生统计 | | `/metrics/bytes` | GET | 获取流量统计 | | `/metrics/nodes` | GET | 获取节点数量(分布式) | | `/metrics/uptime` | GET | 获取服务运行时间 | | `/metrics/bridge` | GET | 获取协议桥接统计 | | `/metrics/plugins` | GET | 获取插件状态统计 | | `/metrics/authentication` | GET | 获取认证成功率统计 | **响应示例** **获取完整监控指标** ```json { "code": 200, "message": "success", "data": { "connections": { "total": 150, "protocols": { "tcp": 50, "udp": 30, "coap": 40, "mqtt": 30 } }, "messages": { "total": 10000, "protocols": { "tcp": 3000, "udp": 2000, "coap": 3500, "mqtt": 1500 } }, "errors": { "total": 10, "protocols": { "tcp": 2, "udp": 1, "coap": 4, "mqtt": 3 } }, "bytes": { "total": 10485760, "protocols": { "tcp": 3145728, "udp": 1048576, "coap": 4194304, "mqtt": 2097152 } }, "bridge": { "mqtt_to_coap": { "total": 500, "success": 480, "rate": 96.0 }, "coap_to_mqtt": { "total": 300, "success": 290, "rate": 96.67 } }, "plugins": { "loaded": 10, "active": 8, "failed": 2 }, "authentication": { "success_rate": 98.5 } } } ``` **获取协议桥接统计** ```json { "code": 200, "message": "success", "data": { "mqtt_to_coap": { "total": 500, "success": 480, "rate": 96.0 }, "coap_to_mqtt": { "total": 300, "success": 290, "rate": 96.67 } } } ``` **获取插件状态统计** ```json { "code": 200, "message": "success", "data": { "loaded": 10, "active": 8, "failed": 2 } } ``` **获取认证成功率统计** ```json { "code": 200, "message": "success", "data": { "success_rate": 98.5 } } ``` ### 五、设备影子 设备影子(Device Shadow)是设备状态的虚拟表示,用于存储和同步设备的当前状态(reported)和期望状态(desired)。当设备离线时,影子会缓存命令,待设备上线后自动推送执行。 **API 接口** | 接口 | 方法 | 说明 | |----------------------------------------------|--------|----------| | `/shadow/{serialNumber}` | GET | 获取设备影子信息 | | `/shadow/desired` | POST | 更新设备期望状态 | | `/shadow/desired/{serialNumber}` | DELETE | 清除期望状态 | | `/shadow/commands` | POST | 添加离线命令 | | `/shadow/commands/{serialNumber}` | GET | 获取离线命令列表 | | `/shadow/command/{serialNumber}/{commandId}` | DELETE | 删除指定命令 | | `/shadow/commands/{serialNumber}` | DELETE | 清空所有命令 | **设备影子结构** ```json { "serialNumber": "TEST0000000000001", "reported": { "temperature": 25.5, "humidity": 60 }, "desired": { "power": "on", "brightness": 80 }, "lastUpdateTime": "2024-01-01 12:00:00", "lastSyncTime": "2024-01-01 12:00:00", "offlineCommands": [], "maxOfflineCommands": 100 } ``` ### 六、健康检查 提供服务健康状态检查接口。 **API 接口** | 接口 | 方法 | 说明 | |-----------|-----|----------| | `/health` | GET | 检查服务健康状态 | **响应示例** ```json { "code": 200, "message": "success", "data": null } ``` *** ## 协议规则模版 ### TCP/UDP 协议规则 **数据类型** | 数据类型 | 描述及要求 | |----------|--------------------------------------| | BYTE | 无符号单字节整型(8位) | | WORD | 无符号双字节整型(16位) | | DWORD | 无符号四字节整型(32位) | | BYTE\[N] | 字节自定义字节数组 | | STRING | 无数据时放0终止符,纯英文符合GB/T1988,含汉字符合GB18030 | **整体结构** | 起始字节 | 字段名称 | 长度(字节) | 数据类型 | 取值规则及说明 | |------|--------|--------|----------|--------------------------------------------------------------------------| | 0 | 起始符 | 2 | STRING | 固定标识:0x260x26(&&) | | 2 | 命令单元 | 2 | BYTE\[2] | 包含命令标识和应答标识,具体规则详见下方命令单元表格。 | | 4 | 时间戳 | 8 | BYTE\[8] | 13位时间戳(毫秒级) | | 12 | 数据加密方式 | 1 | BYTE | 加密规则:`0x01`不加密`0x02`SHA128`0x03`SHA256`0x04`SM2`0x05`RSA`0xFE`异常`0xFF`无效 | | 13 | 数据单元长度 | 2 | WORD | 可变长核心标识:记录数据单元的实际总字节数,有效值0\~65531 | | 15 | 数据单元 | 可变长 | BYTE\[N] |
| | 末尾 | 校验码 | 1 | BYTE | BCC异或校验,范围:命令单元\~数据单元末字节 | **命令单元** | 命令单元组成 | 长度(字节) | 数据类型 | 取值规则及说明 | |--------|--------|------|-----------------------------------------------------------------------------------| | 命令标识 | 1 | BYTE | 0x01:设备登入(上行)0x02:设备登出(上行)0x03:心跳保活(上行)0x04:数据上报(上行)0x05:数据补发(上行)0x06:命令下发(下行) | | 应答标识 | 1 | BYTE | 0x00:表示不需要应答0x01:主动发起方发起0x01(被动接收方应答0x01,表示成功)0x02:主动发起方发起0x01(被动接收方应答0x02,表示未成功) | **数据单元** 4.1 设备登入 | 字段名称 | 长度(字节) | 数据类型 | 取值规则及说明 | |---------|--------|--------|-----------------------------------| | 设备序列号长度 | 1 | BYTE | 记录设备序列号的实际总长度 | | 设备序列号 | N | STRING | 根据“设备序列号长度”字段的取值,截取对应长度的字节作为设备序列号 | | 密钥长度 | 2 | WORD | 记录密钥的实际总长度 | | 密钥 | N | STRING | 根据“密钥长度”字段的取值,截取对应长度的字节作为密钥 | 4.2 设备登出 | 字段名称 | 长度(字节) | 数据类型 | 取值规则及说明 | |---------|--------|--------|-----------------------------------| | 设备序列号长度 | 1 | BYTE | 记录设备序列号的实际总长度 | | 设备序列号 | N | STRING | 根据“设备序列号长度”字段的取值,截取对应长度的字节作为设备序列号 | 4.3 心跳保活 | 字段名称 | 长度(字节) | 数据类型 | 取值规则及说明 | |------|--------|------|---------------------------| | 心跳保活 | 1 | BYTE | 主动发起方固定为 0x00被动接收方应答 0x01 | 4.4 数据上报(可扩展) | 字段名称 | 长度(字节) | 数据类型 | 取值规则及说明 | |---------|--------|----------|-----------------------------------| | 数据类型 | 1 | BYTE | 例:0x01:状态数据 | | 设备序列号长度 | 1 | BYTE | 记录设备序列号的实际总长度 | | 设备序列号 | N | STRING | 根据“设备序列号长度”字段的取值,截取对应长度的字节作为设备序列号 | | 数据长度 | 1 | BYTE | 记录上报数据的实际总长度 | | 上报数据 | N | BYTE\[N] | 实际上报数据(自定义扩展) | 4.5 数据补发(同上) 4.6 命令下发(可扩展) | 字段名称 | 长度(字节) | 数据类型 | 取值规则及说明 | |---------|--------|----------|-----------------------------------| | 命令类型 | 1 | BYTE | 例:0x01:控制开关 | | 命令ID | 8 | BYTE\[8] | 每条下发命令的唯一标识,默认雪花ID | | 设备序列号长度 | 1 | BYTE | 记录设备序列号的实际总长度 | | 设备序列号 | N | STRING | 根据“设备序列号长度”字段的取值,截取对应长度的字节作为设备序列号 | | 命令长度 | 1 | BYTE | 记录命令数据的实际总长度 | | 命令参数 | N | BYTE\[N] | 实际命令参数(自定义扩展) | ### COAP 协议规则 | 参数名称 | 说明 | 示例 | |----------|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| | ack | 是否需要应答,必须 | true/false | | username | 用户名/设备序列号,必须 | - | | password | 密码/密钥,必须 | - | | data | 数据内容,上报、补发必须 | 上报数据,"data" 字段可以为字符串或Json格式,根据实际业务制定,例:{"ack": true, "username": "TEST0000000000001", "password": "\*\*\*\*\*\*", "resource": "status", "data": {}} | | command | 命令内容,控制必须 | 命令参数,"command" 字段可以为字符串或Json格式,根据实际业务制定,例:{"ack": true, "username": "TEST00000000000001", "password": "\*\*\*\*\*\*", "command": "turn\_on\_light"} | | resource | 资源名称,订阅、取消订阅、上报、补发必须 | 例:状态数据 {"ack": true, "username": "TEST0000000000001", "password": "\*\*\*\*\*\*", "resource": "status"} | | status | 应答状态 | ok/error | | message | 消息内容 | success message/error message | **设备登入**
请求路径:coap\://ip:port/login
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001", "password": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=" } ``` 应答消息: ```json { "status": "ok/error", "message": "Login successful/error message" } ``` **设备登出**
请求路径:coap\://ip:port/logout
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001" } ``` 应答消息: ```json { "status": "ok/error", "message": "Logout successful/error message" } ``` **数据上报**
请求路径:coap\://ip:port/report
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001", "password": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=", "resource": "status", "data": "test data report" } ``` 应答消息: ```json { "status": "ok/error", "message": "Data received/error message" } ``` **数据补发**
请求路径:coap\://ip:port/retransmit
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001", "password": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=", "resource": "status", "data": "test data retransmit" } ``` 应答消息: ```json { "status": "ok/error", "message": "Retransmit data received/error message" } ``` **命令下发**
请求路径:coap\://ip:port/control
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001", "password": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=", "command": "turn_on_light" } ``` 应答消息: ```json { "status": "ok/error", "message": "Command executed successfully/error message" } ``` **订阅资源**
请求路径:coap\://ip:port/subscribe
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001", "password": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=", "resource": "status" } ``` 应答消息: ```json { "status": "ok/error", "message": "Subscribed successfully/error message" } ``` **取消订阅**
请求路径:coap\://ip:port/unsubscribe
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001", "password": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=", "resource": "status" } ``` 应答消息: ```json { "status": "ok/error", "message": "Unsubscribed successfully/error message" } ``` **心跳保活**
请求路径:coap\://ip:port/heartbeat
请求方法:POST
请求参数:
```json { "ack": true, "username": "TEST0000000000001", "password": "KmyeXW8umkKXSzEE0/7eLMWILb5fwv3Hr3O0GLDHcyIq1W4=", "message": "ping" } ``` 应答消息: ```json { "status": "ok", "message": "pong" } ``` ### MQTT 协议规则 | 参数名称 | 说明 | 示例 | |----------|---------------|--------------------------------| | ClientID | 客户端标识,必须 | 设备序列号或自定义标识 | | Username | 用户名/设备序列号,必须 | - | | Password | 密码/密钥,必须 | - | | Topic | 消息主题,发布/订阅,必须 | 例:device/status、device/control | | QoS | 服务质量等级,可选 | 0:最多一次1:至少一次2:恰好一次 | | Retain | 保留消息,可选 | true/false | *** ## 待办事项 ### 一、协议完善 - 完善消息主题定义(可按需扩展Topic)和负载格式(数据单元)规范(已标记 TODO) ### 二、功能扩展 - 实现设备上、下线事件的回调机制,通知业务系统(已预留接口,实现通知即可)(已标记 TODO) - 订阅设备影子变化、取消订阅设备影子变化(已预留接口,实现通知即可)(已标记 TODO)