http://swf.com.tw/?p=1002

本系列文章旨在補充《超圖解物聯網IoT實作入門》,採用Arduino、ESP8266和Node.js實作MQTT物聯網通訊實驗。

MQTT是由IBM的Andy Stanford-Clark博士和Arcom(已更名為Eurotech)的Arlen Nipper博士於1999年發明的通訊協定。他們當時是為了在狹窄的網路頻寬和微小電力損耗的需求前提之下,提供石油管線感測器和人造衛星之間一個輕量、可靠的二進制通訊協定。2011年11月,IBM和Eurotech將MQTT協定捐贈給負責管理開放原始碼專案的Eclipse基金會,並且加入Eclipse M2M Industry工作組織。2014年十月,MQTT正式變成一個開放的OASIS國際標準(Organization Advancement Structured Information Standards,資訊標準架構促進會,一個制定電子商務、網路服務和電子出版的非營利機構)。

MQTT最初代表的意思是Message Queueing Telemetry Transport(訊息佇列遙測傳輸),現在已經不用這種說法,MQTT就是MQTT,不是其他單字的縮寫。由於MQTT協定的訊息內容很精簡,非常適合用於處理器資源及網路頻寬有限的物聯網裝置,再加上已經有許多MQTT程式庫被陸續開發出來,用於Arduino控制板(C/C++)、JavaScript(Node.js, Espruino控制板), Python,…等等,還有開放原始碼的MQTT伺服器,使得開發MQTT物聯網、機器之間(Machine-to-Machine, M2M)的通訊變得非常簡單。Facebook Messenger的即時通訊也是用MQTT協定。

採用Arduino和ESP8266實作MQTT之前,本文先提供有關MQTT的背景知識和一些術語說明。

比較HTTP和MQTT通訊協定

MQTT和HTTP的底層都是TCP/IP,也就是物聯網裝置可以沿用既有的網路架構和設備,只是在網路上流通的「訊息格式」以及應用程式的處理機制不同。

假設某個裝置透過Web瀏覽器,以HTTP協定傳送溫度值給網站伺服器,此HTTP POST訊息內容大概像這樣:

除了HTTP請求指令以及代表21度的訊息本體,這段訊息中間夾帶了一堆描述用戶端的的標頭(header)資訊,相當於向伺服器介紹:我來自Chrome瀏覽器、作業系統是Android 7、我讀懂中文和英文…等等。這些額外的標頭訊息在許多物聯網通訊應用不僅僅是多餘的,還會佔用網路頻寬、記憶體並且浪費處理時間。

MQTT訊息格式

採用MQTT發布溫度的訊息格式類似這樣:

不同於HTTP的標頭採用文字描述,MQTT的標頭採用數字編碼,整個長度只佔2位元組,等同兩個字元,後面跟著訊息的主題(topic)和內容(payload),實際格式如下:

MQTT標頭裡的訊息類型、品質…等內容,留待下文說明。除了精簡的標頭,讀者可以發現,MQTT的標頭區並沒有標示傳送目標的IP位址。

MQTT的Publisher, Broker和Subscriber

根據MQTT 3.1.1版本規格書的描述,MQTT是一種基於「發布∕訂閱」機制的訊息傳輸協定(MQTT is a Client Server publish/subscribe messaging transport protocol),我們可以把它想成雜誌發行和訂閱的機制。MQTT訊息發送端,相當於雜誌出版社,雜誌出版之後並不直接寄給消費者,而是交給經銷商或者書店一般的代理人(broker),來統籌管理發行和訂閱事宜。每一個訊息來源(刊物)都有個唯一的主題名稱(刊物名稱)。

代理人是個伺服器軟體,向伺服器發送主題的一方是發布者(publisher),從伺服器獲取主題的一方則是訂閱者(subscriber)。以下圖為例,傳送感測器資料的一邊是發布者,接收感測器資料的一邊則是訂閱者。每個感測器∕微控器的訊息都需要有個主題名稱以利識別,像下圖的主題A、B和C。

代理人(broker)可儲存發布者的訊息,在發布者中斷連線的情況下,提供訂閱者最近更新的訊息。「訂閱者」需要告知代理人想要訂閱的主題,每當「發布者」傳入新訊息時,代理人就會依照主題,傳送給所有訂閱者。「發布者」和「訂閱者」都是用戶端,代理人是伺服器。由於兩個用戶端之間有伺服器當作中繼站,所以兩邊並不需要知道彼此的IP位址。

MQTT的主題(Topic)名稱

MQTT主題名稱是UTF-8(萬國碼)編碼的字串,我們可以自行決定主題名稱,例如,傳送溫度的訊息主題可命名成「溫度」、傳送亮度的訊息主題叫做「照度」…等等。主題名稱也支援類似檔案路徑的階層式命名方式,假設住家裡面有許多感測器,我們可依照測器所在位置,規劃如下的命名階層結構:

每個階層之間用斜線分隔,例如,位於庭院的人體感測器#1,其主題名稱可命名為:

命名主題的注意事項:

  • 由於某些微控器或程式語言不支援UTF-8編碼或中文,主題名稱請使用英文,並且取個有意義的名字。
  • 名稱長度不可超過216位元組(65536個字元)。
  • 自訂的主題名稱請勿用$開頭(“$SYS”是MQTT伺服器的控制介面主題的保留字),也不可包含#和+字元;減號和乘號(*)在程式語言中有特殊意義,為了避免誤會,也不建議使用。
  • 名稱的英文大小寫有區別,home和Home是兩個不同的名稱。
  • 雖然名稱可以包含空格,但是英文的「半形」空格和中文的「全形」空格的內碼不一樣,若輸入名稱時沒有統一,會導致程式讀取不到,因此名稱最好不要加入空格。
  • 階層名稱可以空白,像這樣的命名(連續的斜線)是合法的:“home//yard”,代表有三個階層,中間階層沒有名字,在語意上怪怪的。
  • 有些程式設計師習慣在主題名稱最前面加上一個斜線(在Linux系統中,檔案路徑開頭的斜線代表根目錄),但這是不必要的。請注意,“/home”和“home”是兩個不同的名稱,前者代表「空白名稱的根階層」底下的“home”,單一個“/”也是合法的名稱。

除了依據裝置安裝地點來命名主題,當同一個地點包含許多感測器的時候,用編號或者唯一識別碼來命名主題是比較合理的選擇。例如,假設某個位於廚房的裝置的MAC位址是DEADBEEFFEED,它可以被命名成:

Home/kitchen/DEADBEEFFEED

MQTT教學(一):認識MQTT的更多相关文章

  1. MQTT教學(二):安裝MQTT伺服器Mosquitto,Windows系統篇

    http://swf.com.tw/?p=1005 「認識MQTT」文章提到,MQTT的訊息全都透過稱為代理人(broker)的伺服器交流.本文將說明頗受歡迎的開放原始碼MQTT伺服器Mosquitt ...

  2. [How To] TrueCrypt使用教學 - 重要資訊的加密保險箱(转)

    我在2013年八月的時候寫了這篇關於TrueCrypt的使用教學,但從去年(2014)五月下旬開始,TrueCrypt的首頁出現了"Using TrueCrypt is not secure ...

  3. VPN Gate Client v4.11-免費、無限流量VPN翻牆(跳板)軟體(使用教學)

    VPN Gate Client安裝教學 ▼把下載的檔案壓縮後,開啟安裝檔案. ▼接下來就是一般安裝步驟,下一步>下一步   ▼同意>下一步>下一步   ▼安裝目錄可以用預設的也可以自 ...

  4. 【转】Jollen 的 Android 教學,#12: 如何建立選單 Menu

    原文网址:http://www.jollen.org/blog/2009/06/jollen-android-programming-12.html Android應用程式的UI可以使用XML來定義, ...

  5. 转 【MQTT】在Windows下搭建MQTT服务器

    MQTT简介 MQ 遥测传输 (MQTT) 是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放.简单.轻量.易于实现.这些特点使它适用于受限环境.该协议的特点有: 使用发布/订阅消息模式,提供 ...

  6. MQTT实战2 - 使用MQTTnet实现mqtt通信

    MQTT实战1 - 使用Apache Apollo代理服务器实现mqtt通信 MQTT实战2 - 使用MQTTnet实现mqtt通信 源码下载 -> 提取码  QQ:505645074 MQTT ...

  7. [Java] 歐付寶金流串接教學

    前言: 很多接案的人,都會碰到需要接金流的時候.而歐付寶是個台灣的金流平台. 這邊記錄下,串接的心得.我用的語言是Java, 採liferay這個portal平台,不過這份教學當然適合servlet. ...

  8. 【NS2】NS2 教學手冊(转载)

    之前做毕设的时候搜索NS2的相关资料,发现这个里面涵盖很广,特此收藏,感谢原作者的辛勤劳作. NS2 教學手冊 ( NS2 Learning Guide) [快速連結區] My works  中文影音 ...

  9. Asynchronous MQTT client library for C (MQTT异步客户端C语言库-paho)

    原文:http://www.eclipse.org/paho/files/mqttdoc/MQTTAsync/html/index.html MQTT异步客户端C语言库   用于C的异步 MQTT 客 ...

随机推荐

  1. Burp Suite Extension tools

    1.Setting up the envrionment for burp Extensions   before we can write extensions we need to ensure ...

  2. Flink源码阅读(二)——checkpoint源码分析

    前言 在Flink原理——容错机制一文中,已对checkpoint的机制有了较为基础的介绍,本文着重从源码方面去分析checkpoint的过程.当然本文只是分析做checkpoint的调度过程,只是尽 ...

  3. [S32K]FreeRTOS使用

    参考官方: Tutorial: FreeRTOS 10.0.1 with NXP S32 Design Studio 2018.R1 (官方component是V8.2.1,此文档介绍如何升级到V10 ...

  4. c#版本23个设计模式

    一.引言 对设计模式的学习,自己的感触还是很多的,因为我现在在写代码的时候,经常会想想这里能不能用什么设计模式来进行重构.所以,学完设计模式之后,感觉它会慢慢地影响到你写代码的思维方式.这里对设计模式 ...

  5. 登录-redis

    session的问题 目前session直接是js变量,放在nodejs进程内存中 1.进程内存有限,访问量过大,内存暴增怎么办? 2.正式线上运行是多进程,进程之间内存无法共享 为何session适 ...

  6. Xshell 5连接上suse

    # 关闭防火墙 systemctl stop SuSEfirewall2.service systemctl stop SuSEfirewall2_init.service systemctl dis ...

  7. P2055 [ZJOI2009]假期的宿舍[二分图匹配]

    题目描述 学校放假了 · · · · · · 有些同学回家了,而有些同学则有以前的好朋友来探访,那么住宿就是一个问题. 比如 A 和 B 都是学校的学生,A 要回家,而 C 来看B,C 与 A 不认识 ...

  8. Nginx请求处理流程

    因为 Nginx 运行在企业内网的最外层也就是边缘节点,那么他处理的的流量是其他应用服务器处理流量的数倍,甚至几个数量级,我们知道任何一种问题在不同的数量级下,他的解决方案是完全不同的,所以在 Ngi ...

  9. vue-router路由拦截基本设置,md5加密,js-cookie,vuex刷新页面store中的数据丢失等

    vuex持久化 vuex-persistedstate

  10. spring+mybatis通用dao层、service层的实现

    个人理解: 1.mybatis-spring.jar 提供了SqlSessionTemplate类该类可以对数据库进行CRUD操作(底层其实还是SqlSession) 2.我们可以集成SqlSessi ...