1. 程式人生 > >乾貨 | MQTT協議例析

乾貨 | MQTT協議例析

點選上方“中興開發者社群”,關注我們

每天讀一篇一線開發者原創好文

MQTT(Message Queuing Telemetry Transport,訊息佇列遙測傳輸)是一套ISO標準的基於釋出/訂閱機制的訊息協議,用於在TCP網路中傳輸大規模物聯網裝置資料,是5G通訊的重要服務物件,值得我們花時間去了解學習。IBM於1999年提出MQTT,於2013年將MQTT3.1版本提交給OASIS(Organization for the Advancement of Structured Information Standards )標準化,目前主流的穩定版本為MQTT 3.1.1。MQTT官網為http://mqtt.org/。

本文采用簡單的Node.js程式搭建MQTT基礎環境,介紹MQTT的典型應用場景,以供感興趣的讀者參考和理解。以如下序列圖為例,在MQTT中可能存在三種類型的網元或終端:

  • CLIENT1和CLIENT2為用於釋出(Publish)資料的客戶端(通常是物聯網終端裝置),即“釋出者”。

  • CLIENT3和CLIENT4為用於訂閱(Subscribe)接收資料的客戶端或伺服器(也可能是物聯網終端裝置),即“訂閱者”。

  • BROKER用於中轉資料,各種IoT雲服務平臺通常均支援作為此角色,即“代理”。

  • 方式1:只啟動MQTT服務,預設監聽1883/TCP埠

  1. 命令:mosca -v

  2. 輸出:{"pid":8282,"hostname"

    :"<主機名>","name":"mosca","level":30,"time":1518403379005,"msg":"server started","mqtt":1883,"v":1}

  • 方式2:只啟動MQTTS服務(MQTTS,即MQTT over SSL/TLS),預設監聽8883/TCP埠

  1. 命令:mosca ---key ../cert/server_key_no_password.pem --cert ../cert/server.pem

  2. 輸出:{"pid":8314,"hostname":"<主機名>","name":"mosca","level":30,"time":1518403384861

    ,"msg":"server started","mqtts":8883,"v":1}

  • 方式3:同時啟動MQTT和MQTTS服務,預設監聽1883/TCP埠和8883/TCP埠

  1. 命令:mosca ---key ../cert/server_key_no_password.pem --cert ../cert/server.pem --non-secure

  2. 輸出:{"pid":8333,"hostname":"<主機名>","name":"mosca","level":30,"time":1518403387585,"msg":"server started","mqtt":1883,"mqtts":8883,"v":1}

如圖2所示,BROKER採用mosca方式3啟動,同時支援MQTT和MQTTS服務。

第二步,編寫CLIENT3(MQTT)、CLIENT4(MQTTS)程式以連入BROKER。CLIENT3連入MQTT埠1883,並訂閱“ZTE/test/sk/1”主題。CLIENT4連入MQTTS埠8883,訂閱同樣的“ZTE/test/sk/1”主題,如果該主題收到任何別人釋出的訊息,則CLIENT3、CLIENT4將同時打印出該訊息的內容。

CLIENT3原始碼:

  1. var mqtt =require('mqtt');

  2. var client = mqtt.connect({ port:1883, host:'<BROKER地址>', keepalive:10000});

  3. client.on('connect',function(){

  4.   console.log('CLIENT3: CONNECTED');

  5. });

  6. client.subscribe('ZTE/test/sk/1');

  7. client.on('message',function(topic, message){

  8.   console.log('CLIENT3:', message.toString());

  9. });

CLIENT4原始碼:

  1. var mqtt =require('mqtt');

  2. var fs =require('fs');

  3. var path =require('path');

  4. var TRUSTED_CA_LIST = fs.readFileSync(<