简单介绍

MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。在之前的文章中我们也介绍过好几次使用MQTT:ESP32物联网教程之MQTT(Ardunio IDE)      百度云物联网之MQTT协议创建设备及获取信息.......

本期我们使用C#制作一个MQTT助手,可以实现指定MQTT设备的连接,主题的订阅与取消,消息的接收与发布。

我们简单的设置一下我们的界面,设置了四个文本框用来获取我们的连接信息。

接着我们在NuGet管理包中下载我们的M2MQTT库。

基础部分

在我们的类的顶部使用using 包含我们的库。


using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

接着我们在点击连接的按钮中使用Client的Connect方法连接我们的MQTT服务端


 private void Conect_Click(object sender, EventArgs e)
        {
            if (Conect.Text == "连接")
            {
                string username = UserText.Text;
                string password = PassText.Text;
                string clientName = NameText.Text;
                string address = AddressText.Text;
                client = new MqttClient(address);
                client.Connect(clientName, username, password);
                Console.WriteLine("Connected to MQTT as " + clientName);
                Conect_Click_Connect_Change();
            }
            else
            {
                Conect_Click_Closed_Change();
            }
        }

        private void Conect_Click_Connect_Change()
        {
            UserText.Enabled = false;
            NameText.Enabled = false;
            AddressText.Enabled = false;
            PassText.Enabled = false;
            Conect.Text = "断开连接";
        }

        private void Conect_Click_Closed_Change()
        {
            UserText.Enabled = true;
            NameText.Enabled = true;
            AddressText.Enabled = true;
            PassText.Enabled = true;
            Conect.Text = "连接";
            client.Disconnect();
        }

并且点击连接之后禁用我们的其他控件。

关于MQTT连接信息可以参考公众号的这篇文章:

百度云物联网之MQTT协议创建设备及获取信

接着我们运行一下我们的程序:

我们可以看到我们的MQTT成功进行了连接。

优化

接着我们优化完善一下我们的布局:

我们添加几个文本框还有按钮用来设置我们的订阅信息包括主题还有安全性等等(实际上我们这个库比较简单,这个安全性没啥子用)并且我们在成功连接之前我们禁用这些控件。


 private void AddTopic_Click(object sender, EventArgs e)
        {
            //弹出输入框输入主题
            var userInput = GetUserTopicInput();
            string topic = userInput.topic;
            byte qos = userInput.qos;

            // 首先检查用户输入是否为空
            if (string.IsNullOrEmpty(topic))
            {
                MessageBox.Show("主题不能为空");
                return;
            }

            // 判断TopicBox中是否已包含该主题
            if (TopicBoxtems.Contains(topic))
            {
                MessageBox.Show("主题 " + topic + " 已经存在");
                return;
            }

            // 如果不存在就订阅并添加到TopicBox中
            //client.Subscribe(new[] { topic });
            byte[] byteArray = Encoding.UTF8.GetBytes(SubQOS.Text);

            try
            {
                string[] topics = { topic };
                client.Subscribe(topics, byteArray);
                client.MqttMsgPublishReceived += Client_MqttMsgPublishReceived;
                MessageBox.Show("订阅成功");
            }
            catch (Exception ex)
            {
                MessageBox.Show("订阅失败");
            }
            TopicBox.tems.Add(topic);
            TopicBox.SelectedIndex = 0;
            TransTopic.Items.Add(topic);

        }

        private void UpdateReciveText(string message)
        {
            if (ReciveText.InvokeRequired)
            {
                ReciveText.Invoke(new Action(UpdateReciveText), message);
            }
            else
            {
                // 在 UI 线程上更新 ReciveText 控件
                ReciveText.AppendText(message + "\r\n");
            }
        }

        // 在其他地方调用这个方法,传递要显示的消息


        private void Client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            // 收到发布的消息时执行

            string topic = e.Topic; // 主题
            byte[] payload = e.Message; // 消息负载

            // 处理消息...
            UpdateReciveText("收到主题: " + topic + "\r\n" + "消息: " + Encoding.UTF8.GetString(payload));
            Console.WriteLine("收到主题: " + topic);
            Console.WriteLine("消息: " + Encoding.UTF8.GetString(payload));
        }

        private (string topic, byte qos) GetUserTopicInput()
        {
            string topic = Interaction.InputBox("请输入Topic:", "输入", "");
            byte qos = 0;
            return (topic, qos);
        }

 

这部分代码包括弹出提示框用来输入我们的主题,判断这个主题是否已经被订阅以及订阅我们的主题。

之后设置我们的回调函数用来处理MQTT接收到的信息。

效果展示

运行程序,输入用户名以及密码,之后使用百度云的MQTT服务器端我们是可以接收到数据(图片欠着)。


嘉立创PCB

还没有评论,抢个沙发!