MQTTServer服务器根据MQTTClient客户端已订阅的主题推送 分发消息

网络读卡器介绍:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.4c70645epqZlzn&ft=t&id=626618714746

本示例使用了MQTTNet插件

C# MQTTNETServer 源码

using MQTTnet.Client.Receiving;
using MQTTnet.Server;
using MQTTnet;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MQTTnet.Protocol;

namespace MQTTNETServerForms
{
    public partial class Form1 : Form
    {
        private MqttServerOptionsBuilder optionBuilder;
        private IMqttServer server;//mqtt服务器对象

        List<TopicItem> Topics = new List<TopicItem>();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //创建服务器对象
            server = new MqttFactory().CreateMqttServer();
            server.ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(new Action<MqttApplicationMessageReceivedEventArgs>(Server_ApplicationMessageReceived));//绑定消息接收事件
            server.ClientConnectedHandler = new MqttServerClientConnectedHandlerDelegate(new Action<MqttServerClientConnectedEventArgs>(Server_ClientConnected));//绑定客户端连接事件
            server.ClientDisconnectedHandler = new MqttServerClientDisconnectedHandlerDelegate(new Action<MqttServerClientDisconnectedEventArgs>(Server_ClientDisconnected));//绑定客户端断开事件
            server.ClientSubscribedTopicHandler = new MqttServerClientSubscribedHandlerDelegate(new Action<MqttServerClientSubscribedTopicEventArgs>(Server_ClientSubscribedTopic));//绑定客户端订阅主题事件
            server.ClientUnsubscribedTopicHandler = new MqttServerClientUnsubscribedTopicHandlerDelegate(new Action<MqttServerClientUnsubscribedTopicEventArgs>(Server_ClientUnsubscribedTopic));//绑定客户端退订主题事件
            server.StartedHandler = new MqttServerStartedHandlerDelegate(new Action<EventArgs>(Server_Started));//绑定服务端启动事件
            server.StoppedHandler = new MqttServerStoppedHandlerDelegate(new Action<EventArgs>(Server_Stopped));//绑定服务端停止事件
        }

        /// 绑定消息接收事件
        private void Server_ApplicationMessageReceived(MqttApplicationMessageReceivedEventArgs e)
        {
            string msg = e.ApplicationMessage.ConvertPayloadToString();
            WriteLog(">>> 收到消息:" + msg + ",QoS =" + e.ApplicationMessage.QualityOfServiceLevel + ",客户端=" + e.ClientId + ",主题:" + e.ApplicationMessage.Topic);
        }

        /// 绑定客户端连接事件
        private void Server_ClientConnected(MqttServerClientConnectedEventArgs e)
        {
            Task.Run(new Action(() =>
            {
                lbClients.BeginInvoke(new Action(() =>
                {
                    lbClients.Items.Add(e.ClientId);
                }));
            }));
            WriteLog(">>> 客户端" + e.ClientId + "连接");
        }

        /// 绑定客户端断开事件
        private void Server_ClientDisconnected(MqttServerClientDisconnectedEventArgs e)
        {
            Task.Run(new Action(() =>
            {
                lbClients.BeginInvoke(new Action(() =>
                {
                    lbClients.Items.Remove(e.ClientId);
                }));
            }));
            WriteLog(">>> 客户端" + e.ClientId + "断开");
        }

        /// 绑定客户端订阅主题事件
        private void Server_ClientSubscribedTopic(MqttServerClientSubscribedTopicEventArgs e)
        {
            Task.Run(new Action(() =>
            {
                var topic = Topics.FirstOrDefault(t => t.Topic == e.TopicFilter.Topic);
                if (topic == null)
                {
                    topic = new TopicItem { Topic = e.TopicFilter.Topic, Count = 0 };
                    Topics.Add(topic);
                }
                if (!topic.Clients.Exists(c => c == e.ClientId))
                {
                    topic.Clients.Add(e.ClientId);
                    topic.Count++;
                }

                lvTopic.Invoke(new Action(() =>
                {
                    this.lvTopic.Items.Clear();
                }));

                foreach (var item in this.Topics)
                {

                    lvTopic.Invoke(new Action(() =>
                    {
                        this.lvTopic.Items.Add($"{item.Topic}:{item.Count}");
                    }));
                }
            }));
            WriteLog(">>> 客户端" + e.ClientId + "订阅主题" + e.TopicFilter.Topic);
        }

        /// 绑定客户端退订主题事件
        private void Server_ClientUnsubscribedTopic(MqttServerClientUnsubscribedTopicEventArgs e)
        {
            Task.Run(new Action(() =>
            {
                var topic = Topics.FirstOrDefault(t => t.Topic == e.TopicFilter);
                if (topic != null)
                {
                    topic.Count--;
                    topic.Clients.Remove(e.ClientId);
                }

                this.lvTopic.Items.Clear();
                foreach (var item in this.Topics)
                {
                    this.lvTopic.Items.Add($"{item.Topic}:{item.Count}");
                }
            }));

            WriteLog(">>> 客户端" + e.ClientId + "退订主题" + e.TopicFilter);
        }

        /// 绑定服务端启动事件
        private void Server_Started(EventArgs e)
        {
            WriteLog(">>> 服务端已启动!");
            Invoke(new Action(() => {
                this.button1.Text = "停止服务";
            }));
        }

        /// 绑定服务端停止事件
        private void Server_Stopped(EventArgs e)
        {
            WriteLog(">>> 服务端已停止!");
            Invoke(new Action(() => {
                this.button1.Text = "启动MQTT服务";
            }));
        }

        /// 显示日志
        public void WriteLog(string message)
        {
            if (txtMsg.InvokeRequired)
            {
                txtMsg.Invoke(new Action(() =>
                {
                    txtMsg.Text = "";
                    txtMsg.Text = (message + "\r");
                }));
            }
            else
            {
                txtMsg.Text = "";
                txtMsg.Text = (message + "\r");
            }
        }
       

        [Obsolete]
        private async void button1_Click(object sender, EventArgs e)
        {
            if (button1.Text == "启动MQTT服务")   /// 启动服务
            {
                optionBuilder = new MqttServerOptionsBuilder()
                .WithDefaultEndpointBoundIPAddress(System.Net.IPAddress.Parse(this.txtIP.Text))
                .WithDefaultEndpointPort(int.Parse(this.txtPort.Text))
                .WithDefaultCommunicationTimeout(TimeSpan.FromMilliseconds(5000))
                .WithConnectionValidator(t =>
                {
                    string un = "", pwd = "";
                    un = this.txtUname.Text;
                    pwd = this.txtUpwd.Text;
                    if (t.Username != un || t.Password != pwd)
                    {
                        t.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
                    }
                    else
                    {
                        t.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
                    }
                });
                var option = optionBuilder.Build();
                await server.StartAsync(option);
            }
            else
            {
                if (server != null)   //停止服务
                {                    
                    server.StopAsync();
                }
            }
        }
    }
}

C# MQTTNETClient 源码

using MQTTnet.Client.Options;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MQTTnet;
using static System.Windows.Forms.Design.AxImporter;
using System.Net.Security;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Collections;
using System.Net.Sockets;
using System.Net;



namespace MQTTNETClientForms
{
    public partial class Form1 : Form
    {
        private MqttFactory factory;
        private IManagedMqttClient mqttClient;//客户端mqtt对象
        private MqttClientOptionsBuilder mqttClientOptions;
        private ManagedMqttClientOptionsBuilder options;
        private bool connstate;

        string info = "0";
        string ResponseStr;
        bool AutoResp = true;

        public Form1()
        {
            InitializeComponent();
        }

        public static bool checkip(string ipstr)   //判断IP是否合法
        {
            IPAddress ip;
            if (IPAddress.TryParse(ipstr, out ip))
            { return true; }
            else { return false; }
        }

        public static string getChinesecode(string inputstr)   //获取中文编码,显示汉字、TTS中文语音都要转换编码
        {
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

            int strlen = inputstr.Length;
            string hexcode = "";
            for (int i = 0; i < strlen; i++)
            {
                string str = inputstr.Substring(i, 1);
                byte[] Chinesecodearry = System.Text.Encoding.GetEncoding(936).GetBytes(str);
                int codelen = (byte)Chinesecodearry.Length;
                if (codelen == 1)
                {
                    hexcode = hexcode + str;
                }
                else
                {
                    hexcode = hexcode + "\\x" + Chinesecodearry[0].ToString("X2") + Chinesecodearry[1].ToString("X2");
                }
            }
            return hexcode;
        }

        public static string getjsonval(string totalstr, string namestr)    //解析JSON数据
        {
            string valustr = "";
            totalstr = totalstr.Replace("{", "");
            totalstr = totalstr.Replace("}", "");
            totalstr = totalstr.Replace("\"", "");
            string[] dataArray = totalstr.Split(new char[2] { ',', ',' });
            if (dataArray.GetUpperBound(0) > 0)
            {
                for (int i = 0; i < dataArray.Length; i++)
                {
                    string[] dataArray2 = dataArray[i].Split(new char[2] { ':', ':' });
                    if (dataArray2[0] == namestr)
                    {
                        valustr = dataArray2[1];
                        break;
                    }
                }
            }
            return valustr;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string computerName = System.Net.Dns.GetHostName();
            txtId.Text = computerName;

            comboBox1.SelectedIndex = 1;
            comboBox2.SelectedIndex = 0;
            comboBox_server.SelectedIndex = 0;
        }

        /// 显示日志--------------------------------------------------------------------------------------------------------
        private void WriteLog(string message)
        {
            if (txtMsg.InvokeRequired)
            {
                txtMsg.Invoke(new Action(() =>
                {
                    txtMsg.Text = (message);
                    listBox1.Items.Add(message);
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;
                }));
            }
            else
            {
                txtMsg.Text = (message);
                listBox1.Items.Add(message);
                listBox1.SelectedIndex = listBox1.Items.Count - 1;
            }
        }

        /// 订阅----------------------------------------------------------------------------------------------------------------
        [Obsolete]
        private async void btnSub_Click(object sender, EventArgs e)
        {
            if (connstate == false)
            {
                WriteLog(">>> 请先与MQTT服务器建立连接!");
                return;
            }

            if (string.IsNullOrWhiteSpace(this.txtTopic.Text))
            {
                WriteLog(">>> 请输入主题");
                return;
            }
            //在 MQTT 中有三种 QoS 级别: 
            //At most once(0) 最多一次
            //At least once(1) 至少一次
            //Exactly once(2) 恰好一次
            //await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(this.tbTopic.Text).WithAtMostOnceQoS().Build());//最多一次, QoS 级别0
            await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic(this.txtTopic.Text).WithAtLeastOnceQoS().Build());//恰好一次, QoS 级别1 
            WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 成功订阅");
        }

        /// 发布------------------------------------------------------------------------------------------------------------------------------
        private async void button1_Click(object sender, EventArgs e)
        {
            if (!checkip(comboBox_server.Text))
            {
                MessageBox.Show("请输入正确的MQTT服务器IP。", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }


            if (button1.Text == "连接到MQTT服务器")
            {
                connstate = false;

                factory = new MqttFactory();
                mqttClient = factory.CreateManagedMqttClient();//创建客户端对象

                //绑定断开事件
                mqttClient.UseDisconnectedHandler(async ee =>
                {
                    WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 与服务器之间的连接断开了,正在尝试重新连接");
                    Invoke(new Action(() =>
                    {
                        this.button1.Text = "连接到MQTT服务器";
                        this.comboBox_server.Enabled = true;
                    }));
                    // 等待 5s 时间
                    await Task.Delay(TimeSpan.FromSeconds(5));
                    try
                    {
                        if (factory == null) { factory = new MqttFactory(); }//创建客户端对象 
                        if (mqttClient == null) { mqttClient = factory.CreateManagedMqttClient(); }//创建客户端对象 

                        mqttClient.UseConnectedHandler(tt =>
                        {
                            connstate = true;
                            WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 连接到服务成功");
                            Invoke(new Action(() =>
                            {
                                // 更新UI的代码
                                this.button1.Text = "断开与MQTT服务器的连续";
                                this.comboBox_server.Enabled = false;
                                this.btnSub.PerformClick();
                            }));
                        });
                    }
                    catch (Exception ex)
                    {
                        connstate = false;
                        WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + $" >>> 重新连接服务器失败:{ex}");

                        Invoke(new Action(() =>
                        {
                            this.button1.Text = "连接到MQTT服务器";
                            this.comboBox_server.Enabled = true;
                        }));
                    }
                });

                //绑定接收事件
                mqttClient.UseApplicationMessageReceivedHandler(aa =>
                {
                    try
                    {
                        string msg = aa.ApplicationMessage.ConvertPayloadToString();
                        WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 消息:" + msg + ",QoS =" + aa.ApplicationMessage.QualityOfServiceLevel + ",客户端=" + aa.ClientId + ",主题:" + aa.ApplicationMessage.Topic);

                        if (AutoResp)  //选择接收到消息立即回应
                        {
                            info = getjsonval(msg, "info");
                            string jihao = getjsonval(msg, "jihao");
                            string cardtype = getjsonval(msg, "cardtype");
                            string card = getjsonval(msg, "card");
                            string dn = getjsonval(msg, "dn");

                            Invoke(new Action(() =>
                            {
                                this.button3.PerformClick();
                            }));
                        }
                    }
                    catch (Exception ex)
                    {
                        WriteLog($"+ 消息 = " + ex.Message);
                    }
                });

                //绑定连接事件
                mqttClient.UseConnectedHandler(ee =>
                {
                    connstate = true;
                    WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + " >>> 连接到服务成功");

                    Invoke(new Action(() =>
                    {
                        this.button1.Text = "断开与MQTT服务器的连续";
                        this.comboBox_server.Enabled = false;
                        this.btnSub.PerformClick();
                    }));

                });

                var mqttClientOptions = new MqttClientOptionsBuilder()
                      .WithClientId(this.txtId.Text)
                      .WithTcpServer(this.comboBox_server.Text, int.Parse(this.txtPort.Text))
                      .WithCredentials(this.txtName.Text, this.txtUpwd.Text);

                var options = new ManagedMqttClientOptionsBuilder()
                            .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
                            .WithClientOptions(mqttClientOptions.Build())
                            .Build();
                //开启
                await mqttClient.StartAsync(options);
            }
            else
            {
                if (mqttClient != null)
                {
                    if (mqttClient.IsStarted)
                    {
                        await mqttClient.StopAsync();
                    }
                    mqttClient.Dispose();
                    connstate = false;
                }

                button1.Text = "连接到MQTT服务器";
                comboBox_server.Enabled = true;
            }
        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private async void button2_Click(object sender, EventArgs e)
        {
            if (connstate == false)
            {
                WriteLog(">>> 请先与MQTT服务器建立连接!");
                return;
            }

            if (string.IsNullOrWhiteSpace(this.textBox1.Text))
            {
                WriteLog(">>> 请输入主题");
                return;
            }
            var result = await mqttClient.PublishAsync(
                this.textBox1.Text,
                this.txtContent.Text,
                MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);//恰好一次, QoS 级别1   
            WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + $" >>> 主题:{this.textBox1.Text},消息:{this.txtContent.Text},结果: {result.ReasonCode}");
        }

        private async void button3_Click(object sender, EventArgs e)
        {
            if (comboBox2.SelectedIndex == 0)
            {
                ResponseStr = "Response=1";
                ResponseStr = ResponseStr + "," + info;
                if (checkBox2.Checked)
                {
                    ResponseStr = ResponseStr + "," + getChinesecode(disptext.Text.Trim());
                    ResponseStr = ResponseStr + "," + delaytime.Value.ToString();
                }
                else
                {
                    ResponseStr = ResponseStr + ",";
                    ResponseStr = ResponseStr + ",";
                }

                if (checkBox4.Checked)
                {
                    ResponseStr = ResponseStr + "," + comboBox1.SelectedIndex.ToString();
                }
                else
                {
                    ResponseStr = ResponseStr + ",";
                }

                if (checkBox3.Checked)
                {
                    ResponseStr = ResponseStr + "," + getChinesecode("[" + Volume.Value.ToString() + "]" + voicetext.Text.Trim());
                }
                else
                {
                    ResponseStr = ResponseStr + ",";
                }

                if (checkBox5.Checked)
                {
                    ResponseStr = ResponseStr + "," + switch1.Value.ToString();
                }
                else
                {
                    ResponseStr = ResponseStr + ",";
                }

                if (checkBox6.Checked)
                {
                    ResponseStr = ResponseStr + "," + switch2.Value.ToString();
                }
                else
                {
                    ResponseStr = ResponseStr + ",";
                }
            }
            else
            {
                ResponseStr = "{\"Response\":\"json\",\"infotype\":\"1\"";
                ResponseStr = ResponseStr + ",\"info\":\"" + info + "\"";
                if (checkBox2.Checked)
                {
                    ResponseStr = ResponseStr + ",\"disp\":\"" + getChinesecode(disptext.Text.Trim()) + "\"";
                    ResponseStr = ResponseStr + ",\"dispdelay\":\"" + delaytime.Value.ToString() + "\"";
                }

                if (checkBox4.Checked)
                {
                    ResponseStr = ResponseStr + ",\"beeptype\":\"" + comboBox1.SelectedIndex.ToString() + "\"";
                }

                if (checkBox3.Checked)
                {
                    ResponseStr = ResponseStr + ",\"voicetype\":\"" + getChinesecode("[" + Volume.Value.ToString() + "]" + voicetext.Text.Trim()) + "\"";
                }

                if (checkBox5.Checked)
                {
                    ResponseStr = ResponseStr + ",\"k1delay\":\"" + switch1.Value.ToString() + "\"";
                }

                if (checkBox6.Checked)
                {
                    ResponseStr = ResponseStr + ",\"k2delay\":\"" + switch2.Value.ToString() + "\"";
                }
            }

            var result = await mqttClient.PublishAsync(
                this.txtTopik.Text,
                this.ResponseStr,
                MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce);//恰好一次, QoS 级别1   
            WriteLog(DateTime.Now.ToLocalTime().ToString("HH:mm:ss.fff") + $" >>> 主题:{this.txtTopik.Text},消息:{this.ResponseStr},结果: {result.ReasonCode}");

        }

        private void checkBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (checkBox1.Checked) { AutoResp = true; } else { AutoResp = false; }
        }

        private void listBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (listBox1.SelectedIndex >= 0)
            {
                txtMsg.Text = listBox1.Text;
            }
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vx_13822155058

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值