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環境。
運行成功的界面

4在瀏覽器查看連接的狀況
在瀏覽器輸入 http://127.0.0.1:61680/ 或者 https://127.0.0.1:61681/,默認賬號 admin,密碼 password

在這里看當前連接狀況
阿里雲 Mqtt搭建
1,首先要上阿里雲購買服務
購買地址https://common-buy.aliyun.com/?commodityCode=onsMqtt#/buy
購買成功進入控制台

要是看不到實例列表的話,注意是否選擇對了區域,默認是公網,我這里是華南區
選擇group管理

創建一個新的groupid
然后就可以使用應用程序連接了
常用的net mqtt庫有MQTTnet,M2Mqtt我這里使用 MQTTnet

使用Nuget安裝

此處的username和pwd需要從阿里雲賬戶里面獲取

在右上角獲取

這個分別就是key和secret
然后連接mqtt的時候username用key
Pwd用groupid加secret的哈希算法得來

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;
}
連接地址
在阿里雲的控制台獲取 即接入點域名 ,這里就不再需要端口號了


連接成功

4 客戶端測試工具
添加MqttLens
使用谷歌瀏覽器 打開谷歌插架商店搜索MqttLens 並添加到瀏覽器
添加成功后在瀏覽器打開chrome://apps/

點擊運行添加一個連接

測試發布訂閱

測試成功
5 遺囑和消息格式
遺囑
遺囑是mqtt的一個大特點
遺囑的原理:連接成功后立即往往broker發送一條消息(遺囑),但不生效,當客戶端斷開連接,broker檢測不到心跳時,遺囑生效。
消息格式
消息格式應當是下功夫去定義的,好的topic格式可以讓我們更簡潔方便
三種符號
/ 代表層級 一般定義消息時都以 /分割成層級
比如 家具/飲水機/加熱
通配符+ 代表一層匹配
比如


比如有設備 飲水機想要訂閱 加熱和保溫兩個topic,只需要訂閱家具/飲水機/+
全通配符 # 能完全匹配,不限制層數

6 各種broker服務器對比
Apollo 免費 數量少沒問題,數量大就不是很穩定了。而且實測時連接數和機器的內核數有關比如我這里4核的 WinServer最多只能連上512個
EMQ 國產的。也有免費版。各種服務器的版本都有,也很不錯,
這里是官網 http://www.emqtt.com/
阿里雲微消息服務如果可靠性要求比較高,或者客戶端的數量比較大時,推薦使用阿里雲。價格也不是很貴,安全性高,穩定性很高,這里還是很推薦。
