用 C# + MQTTnet 4.2 做智能家居控制板远程控制
智能家居控制板通过 MQTT 上报状态、接收指令。服务端用 MQTTnet 4.2 连到 fsxzy.cn:1883,做一个 WinForms 客户端来集中管理。下面是实现要点。
1. 建立连接
MQTTnet 4.x 的 API 和 3.x 差别很大,MqttFactory + MqttClientOptionsBuilder 是标准姿势:
var factory = new MqttFactory();
var client = factory.CreateMqttClient();
var options = new MqttClientOptionsBuilder()
.WithTcpServer("fsxzy.cn", 1883)
.WithClientId("mgr-" + Guid.NewGuid().ToString("N").Substring(0, 8))
.WithCredentials("user", "password")
.WithCleanSession()
.Build();
await client.ConnectAsync(options, CancellationToken.None);
2. 订阅与下发
每台控制板一个主题前缀,比如 lift/{sn}/state 上报、lift/{sn}/cmd 下发:
await client.SubscribeAsync("lift/+/state");
client.ApplicationMessageReceivedAsync += e =>
{
var topic = e.ApplicationMessage.Topic;
var payload = Encoding.UTF8.GetString(e.ApplicationMessage.PayloadSegment);
// 解析状态、刷新 UI(注意跨线程回主线程)
return Task.CompletedTask;
};
var msg = new MqttApplicationMessageBuilder()
.WithTopic($"lift/{sn}/cmd")
.WithPayload(JsonSerializer.Serialize(cmd))
.WithQualityOfServiceLevel(MqttQualityOfServiceLevel.AtLeastOnce)
.Build();
await client.PublishAsync(msg, CancellationToken.None);
3. 断线重连与保活
- 监听
DisconnectedAsync,用Task.Delay做指数退避重连; - 设
WithKeepAlivePeriod(TimeSpan.FromSeconds(30)),掉线能更快被发现; - 重连成功后重新订阅(Clean Session 下订阅会丢)。
易错点:WinForms 里收到消息是在网络线程,直接改控件会抛跨线程异常,记得 Invoke() 回 UI 线程。
整体结构跑通后,再加设备列表、指令模板和历史日志就成了一个能用的管理平台。
← 返回首页