# GoMQTT **Repository Path**: clint315/gomqtt ## Basic Information - **Project Name**: GoMQTT - **Description**: Go语言版的mqtt客户端 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-10-15 - **Last Updated**: 2025-10-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # GoMQTT 示例 提供两种 MQTT 客户端实现: 1. **lib**: 使用官方 **eclipse/paho.mqtt.golang** 库封装的**完整** MQTT 客户端实现,支持: - QoS 0/1/2 消息传递 - 自动重连和连接重试 - TLS/SSL 加密连接 - 遗嘱消息 (Last Will) - Retain 消息 - 通配符主题订阅 - 连接状态回调 - 完整的错误处理 2. **manual**: 手动实现的最小 MQTT 3.1.1 协议客户端: - 支持基本的 CONNECT/CONNACK/PUBLISH/SUBSCRIBE/PINGREQ/DISCONNECT - 仅支持 QoS 0 - 单连接,无自动重连 - 适合学习 MQTT 协议原理 ## 目录结构 ``` internal/ ├── core/ # 公共接口与类型定义 │ └── types.go ├── libwrap/ # Paho MQTT 完整封装客户端 │ └── client.go └── manual/ # 手动实现的最小协议客户端 ├── client.go └── packet.go cmd/ ├── lib/ # Paho 库示例程序 │ └── main.go └── manual/ # 手动实现示例程序 └── main.go ``` ## 快速开始 ### 前提条件 需要本地或远端 MQTT Broker(如 mosquitto)监听 `tcp://localhost:1883`。 使用 Docker 快速启动 Mosquitto: ```bash make docker-mosquitto # 或者 docker run -d --name mosquitto -p 1883:1883 eclipse-mosquitto:latest ``` ### 诊断连接问题 如果遇到连接问题,使用诊断工具: ```bash make diagnostic ``` 诊断工具会: - 测试 MQTT Broker 连接(10 秒超时) - 显示详细的错误信息 - 提供快速修复建议 ### 安装依赖 ```bash make deps # 或者 go mod download go mod tidy ``` ### 运行示例 **Paho 库完整实现(推荐):** ```bash make run-lib # 或者 go run ./cmd/lib ``` **手动实现(学习用):** ```bash make run-manual # 或者 go run ./cmd/manual ``` ### 编译 ```bash make build ``` 编译后的二进制文件位于 `bin/` 目录: - `bin/lib` - Paho 库示例 - `bin/manual` - 手动实现示例 ## 核心接口 核心接口定义在 `internal/core/types.go`: ```go type Client interface { // Connect 连接到 MQTT Broker Connect(ctx context.Context, opts Options) error // Publish 发布消息(默认 QoS 0) Publish(ctx context.Context, topic string, payload []byte) error // PublishQoS 发布消息,支持指定 QoS 和 Retain PublishQoS(ctx context.Context, topic string, qos byte, retain bool, payload []byte) error // Subscribe 订阅主题(默认 QoS 0) Subscribe(ctx context.Context, topic string, handler Handler) error // SubscribeQoS 订阅主题,支持指定 QoS SubscribeQoS(ctx context.Context, topic string, qos byte, handler Handler) error // Unsubscribe 取消订阅 Unsubscribe(ctx context.Context, topic string) error // IsConnected 检查连接状态 IsConnected() bool // Close 关闭连接 Close() error } // Options 连接配置 type Options struct { Broker string // Broker 地址,如 "tcp://localhost:1883" ClientID string // 客户端唯一标识 Username string // 用户名(可选) Password string // 密码(可选) CleanSession bool // 清洁会话 KeepAlive uint16 // 心跳间隔(秒) AutoReconnect bool // 自动重连 MaxReconnectInterval int // 最大重连间隔(秒) ConnectRetry bool // 连接重试 ConnectRetryInterval int // 连接重试间隔(秒) TLSEnabled bool // 启用 TLS WillEnabled bool // 启用遗嘱消息 WillTopic string // 遗嘱主题 WillPayload []byte // 遗嘱消息内容 WillQoS byte // 遗嘱消息 QoS WillRetain bool // 遗嘱消息 Retain OnConnect func() // 连接成功回调 OnConnectionLost func(err error) // 连接丢失回调 OnReconnecting func() // 重连中回调 } // Handler 消息处理函数 type Handler func(topic string, payload []byte) ``` ## 使用示例 ### Paho 库版本(完整实现) ```go package main import ( "context" "log" "github.com/clint/gomqtt/internal/core" "github.com/clint/gomqtt/internal/libwrap" ) func main() { // 创建客户端 client := libwrap.NewClient() // 配置选项 opts := core.DefaultOptions() opts.Broker = "tcp://localhost:1883" opts.ClientID = "my-client" opts.AutoReconnect = true // 设置回调 opts.OnConnect = func() { log.Println("已连接") } opts.OnConnectionLost = func(err error) { log.Printf("连接丢失: %v\n", err) } // 连接 ctx := context.Background() if err := client.Connect(ctx, opts); err != nil { log.Fatal(err) } defer client.Close() // 订阅主题(QoS 1) client.SubscribeQoS(ctx, "test/topic", 1, func(topic string, payload []byte) { log.Printf("收到: [%s] %s\n", topic, string(payload)) }) // 发布消息(QoS 1,Retain) client.PublishQoS(ctx, "test/topic", 1, true, []byte("Hello MQTT!")) // ... 应用逻辑 ... } ``` ### 手动实现版本(简化版) ```go package main import ( "context" "log" "github.com/clint/gomqtt/internal/core" "github.com/clint/gomqtt/internal/manual" ) func main() { client := manual.NewClient() opts := core.DefaultOptions() opts.Broker = "tcp://localhost:1883" opts.ClientID = "my-manual-client" ctx := context.Background() if err := client.Connect(ctx, opts); err != nil { log.Fatal(err) } defer client.Close() // 仅支持 QoS 0 client.Subscribe(ctx, "test/topic", func(topic string, payload []byte) { log.Printf("收到: [%s] %s\n", topic, string(payload)) }) client.Publish(ctx, "test/topic", []byte("Hello from Manual!")) } ``` ## 功能对比 | 功能 | Paho 库版本 | 手动实现版本 | |------|------------|-------------| | QoS 0 | ✅ | ✅ | | QoS 1 | ✅ | ❌ | | QoS 2 | ✅ | ❌ | | 自动重连 | ✅ | ❌ | | TLS/SSL | ✅ | ❌ | | 遗嘱消息 | ✅ | ✅ (基础) | | Retain 消息 | ✅ | ✅ | | 通配符订阅 | ✅ | ✅ | | 连接回调 | ✅ | ✅ (基础) | | WebSocket | ✅ | ❌ | | 会话恢复 | ✅ | ❌ | | 消息队列 | ✅ | ❌ | ## Make 命令 ```bash make help # 显示帮助信息 make deps # 下载并整理依赖 make build # 编译所有示例程序 make run-lib # 运行 Paho 库示例 make run-manual # 运行手动实现示例 make test # 运行测试 make clean # 清理编译输出 make fmt # 格式化代码 make vet # 运行 go vet make lint # 代码检查(fmt + vet) make docker-mosquitto # 启动 Mosquitto Broker (Docker) ``` ## 测试 MQTT Broker ### 使用 mosquitto_sub 测试订阅 ```bash mosquitto_sub -h localhost -t "test/#" -v ``` ### 使用 mosquitto_pub 测试发布 ```bash mosquitto_pub -h localhost -t "test/topic" -m "Hello MQTT" ``` ## 架构设计 ### 接口抽象 通过 `internal/core/types.go` 定义统一的 `Client` 接口,使得两种实现可以互换使用,便于测试和扩展。 ### Paho 库封装 (libwrap) - 完整封装 paho.mqtt.golang 的所有功能 - 统一错误处理和上下文管理 - 支持所有 MQTT 3.1.1 特性 - 生产环境推荐使用 ### 手动实现 (manual) - 直接操作 TCP 连接和 MQTT 协议包 - 实现 CONNECT、PUBLISH、SUBSCRIBE、PING、DISCONNECT - 代码简洁,适合学习 MQTT 协议细节 - 仅用于教学和简单场景 ## 依赖 - Go 1.21+ - [eclipse/paho.mqtt.golang](https://github.com/eclipse/paho.mqtt.golang) v1.4.3 ## 后续改进想法 - [x] ✅ 完整的 QoS 支持(通过 Paho 库实现) - [x] ✅ 自动重连机制(通过 Paho 库实现) - [x] ✅ TLS/SSL 支持(通过 Paho 库实现) - [x] ✅ 遗嘱消息和 Retain(通过 Paho 库实现) - [ ] 添加更多单元测试 - [ ] 性能基准测试 - [ ] 集成测试(需要实际 MQTT Broker) - [ ] 完善手动实现的 QoS 1/2 - [ ] WebSocket 支持示例 - [ ] MQTT 5.0 支持 ## 许可证 MIT License ## 参考资料 - [MQTT 3.1.1 规范](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html) - [Eclipse Paho](https://www.eclipse.org/paho/) - [Paho Go Client](https://github.com/eclipse/paho.mqtt.golang)