1,简介

MQTT协议(Message Queuing Telemetry Transport),翻译过来就是遥信消息队列传输,是IBM公司于1999年提出的,现在最新版本是3.1.1。MQTT是一个基于TCP的发布订阅协议,设计的初始目的是为了极有限的内存设备和网络带宽很低的网络不可靠的通信,非常适合物联网通信

特点:

1轻量,

2可以在网络差的环境中使用  

3 使用发布订阅模式

4遗嘱

5消息有三种QOS(消息质量)0只发布不管关心不收到,1最少收到一次,2确保收到一次,只一次)


     越来越的的物联网,互联网应用在使用Mqtt协议,小黄车就是其中之一 。可以被用作即时通讯,消息队列,消息推送(智联招聘企业版就使用mqtt做前端的消息推送)等等。各种语言的成熟库都有。

        总之就是很棒,应用很广,将来会更广。

2 C#中使用Mqtt

Net也很多库

我们这里使用MQTTnet

using MQTTnet;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace AliyunMqtt2
{
    class Program
    {

        static void Main(string[] args)
        {
    
            string CId = "1";                   //用户标识ID
            String userName = "admin";         //用户名
            String passWord = "password";          //密码
            var will = new MqttApplicationMessage() { Topic = "lastwill", Payload = System.Text.Encoding.UTF8.GetBytes("我掉线了") };//定义遗嘱消息



         
       

            IMqttClientOptions Option = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1", 61613)//地址端口号
          .WithClientId(CId)                                            //客户端标识Id要唯一。
          .WithCredentials(userName, passWord)                          //用户名,密码
          .WithWillMessage(will)                                         //加上遗嘱消息
           .WithCleanSession() 
           .Build();

            MqttFactory factory = new MqttFactory();
            var mqttClient = factory.CreateMqttClient();   //创建客户端实例


            mqttClient.Connected += (object sender, MqttClientConnectedEventArgs e) =>         //连接成功
            {
                Console.WriteLine("连接成功:" + CId);


                var topics = new List<TopicFilter>();
                topics.Add(new TopicFilter() { Topic = "家具/#" });

                mqttClient.SubscribeAsync(topics);//订阅
                Console.WriteLine("订阅成功:");

                mqttClient.PublishAsync("家具/饮水机/加热/10度", "10");//发布
                Console.WriteLine("发布成功");

            };
            mqttClient.Disconnected += (object sender, MqttClientDisconnectedEventArgs e) =>
            {
                Console.WriteLine("断开连接:" + CId);


            };
            mqttClient.ApplicationMessageReceived += (object sender, MqttApplicationMessageReceivedEventArgs e) =>
            {
                ///收到消息
                string content = System.Text.Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                Console.WriteLine($"收到消息 msg={content}:");


            };
           
                mqttClient.ConnectAsync(Option);

         
            Console.ReadLine();
         
        }


    }
}

  

3 Broker服务搭建

Mqtt需要一个Broker服务器做消息的中转站,所有的客户端发布都是往broker发布,订阅也都是从broker订阅

这里我们介绍两种broker,免费简单的apollo和稳定高性能的阿里云mqtt服务

Apollo

1.下载地址 http://activemq.apache.org/apollo/download.html

2.创建一个broker实例,命令行cd到bin目录,执行/bin/apollo create mybroker,执行后就会在bin目录下创建mybroker文件夹。

3.运行broker实例,命令行cd到mybroker/bin目录,执行mybroker/bin/apollo-broker.cmd run

:apollo依赖java环境。

运行成功的界面

mqtt协议java mqtt协议怎么用_mqtt .Net  消息推送

 


4在浏览器查看连接的状况

在浏览器输入 http://127.0.0.1:61680/ 或者 https://127.0.0.1:61681/,默认账号 admin,密码 password

 

mqtt协议java mqtt协议怎么用_Text_02

 

在这里看当前连接状况


 


 

 

阿里云 Mqtt搭建

 

 

1,首先要上阿里云购买服务

购买地址https://common-buy.aliyun.com/?commodityCode=onsMqtt#/buy

 

购买成功进入控制台

 

mqtt协议java mqtt协议怎么用_mqtt协议java_03

 

要是看不到实例列表的话,注意是否选择对了区域,默认是公网,我这里是华南区

 

选择group管理

 

mqtt协议java mqtt协议怎么用_客户端_04

 

创建一个新的groupid

 

然后就可以使用应用程序连接了

 

常用的net mqtt库有MQTTnet,M2Mqtt我这里使用 MQTTnet

 

 

mqtt协议java mqtt协议怎么用_客户端_05

 

 

使用Nuget安装

 

mqtt协议java mqtt协议怎么用_Text_06

 

 

此处的username和pwd需要从阿里云账户里面获取

 

 

mqtt协议java mqtt协议怎么用_System_07

 

在右上角获取

 

mqtt协议java mqtt协议怎么用_mqtt协议java_08

 

这个分别就是key和secret

 

然后连接mqtt的时候username用key

Pwd用groupid加secret的哈希算法得来

 

mqtt协议java mqtt协议怎么用_mqtt协议java_09

 

 

   public static string HMACSHA1(string key, string dataToSign)

        {

            Byte[] secretBytes = UTF8Encoding.UTF8.GetBytes(key);

            HMACSHA1 hmac = new HMACSHA1(secretBytes);

            Byte[] dataBytes = UTF8Encoding.UTF8.GetBytes(dataToSign);

            Byte[] calcHash = hmac.ComputeHash(dataBytes);

            String calcHashString = Convert.ToBase64String(calcHash);

            return calcHashString;

        }

 

 

 

 

连接地址

在阿里云的控制台获取 即接入点域名 ,这里就不再需要端口号了

 

mqtt协议java mqtt协议怎么用_mqtt协议java_10

 

 

mqtt协议java mqtt协议怎么用_mqtt .Net  消息推送_11

 

 

 

 

 

连接成功

 

mqtt协议java mqtt协议怎么用_mqtt .Net  消息推送_12

 

4 客户端测试工具

 

添加MqttLens

 

使用谷歌浏览器 打开谷歌插架商店搜索MqttLens 并添加到浏览器

 

添加成功后在浏览器打开chrome://apps/

 

mqtt协议java mqtt协议怎么用_mqtt协议java_13

 

点击运行添加一个连接

 

mqtt协议java mqtt协议怎么用_客户端_14

 

测试发布订阅

 

mqtt协议java mqtt协议怎么用_mqtt .Net  消息推送_15

 

测试成功

 

 

 

 

5 遗嘱和消息格式

遗嘱

 

遗嘱是mqtt的一个大特点

 

遗嘱的原理:连接成功后立即往往broker发送一条消息(遗嘱),但不生效,当客户端断开连接,broker检测不到心跳时,遗嘱生效。

消息格式

消息格式应当是下功夫去定义的,好的topic格式可以让我们更简洁方便

三种符号

/  代表层级 一般定义消息时都以 /分割成层级

 

比如  家具/饮水机/加热

 

通配符+ 代表一层匹配

 

比如

 

mqtt协议java mqtt协议怎么用_mqtt .Net  消息推送_16

mqtt协议java mqtt协议怎么用_客户端_17

 

 

比如有设备 饮水机想要订阅 加热和保温两个topic,只需要订阅家具/饮水机/+

 

 

全通配符  # 能完全匹配,不限制层数

 

 

mqtt协议java mqtt协议怎么用_mqtt .Net  消息推送_18

 

6  各种broker服务器对比

Apollo 免费 数量少没问题,数量大就不是很稳定了。而且实测时连接数和机器的内核数有关比如我这里4核的 WinServer最多只能连上512个