手把手教你入門AIoT(10)

本課程會深入淺出地介紹 MQTT 協議的各種特性,對每個協議特性都輔以具體代碼進行講解,並通過一個 IoT+AI 項目實戰來具體展現 MQTT 在移動端、Web 端的使用,MQTT Broker 的架設等場景。

內容如下:

1.MQTT協議簡介

2.MQTT的基礎概念

3.建議到MQTT Broker的鏈接(1)

4.建議到MQTT Broker的鏈接(2)

5.訂閱和發佈模型

6.訂閱一個主題

7.QoS0和QoS1是什麼

8.QoS2和QoS的最佳實踐

9.Retained消息和LWT

10.Keep Alive和鏈接保活

11.實踐課IoT+AI之發佈端

12.實踐課IoT+AI之Web訂閱端

13.搭建MQTT Broker和安全實踐

在這一課裏我們來實現 Web 訂閱端。本節課核心內容:

  • MQTT over WebSocket

  • 連接到 Broker

  • 處理消息

MQTT over WebSocket

我們要實現的是一個可以在瀏覽器裏運行的 MQTT Client。MQTT 基於 TCP 協議,在目前主流的瀏覽器裏面,使用 JavaScript 直接打開一個 TCP 連接是不可能的,所以在瀏覽器裏面直接使用 MQTT 目前是沒有辦法的。

Socket API 可以解決這個問題,但是瀏覽器對 Socket API 的支持還非常有限。而我們可以應用 MQTT over WebSocket 來在瀏覽器中使用 MQTT,因爲大部分主流瀏覽器都支持 WebSocket。MQTT over WebSocket 實現原理是把 MQTT 數據包封裝在 WebSocket 幀裏進行發送:

MQTT over WebSocket 也需要 Broker 支持,不過目前大部分 Broker 都是支持的,包括本課程裏面使用的 Public Broker。

連接到 Broker

首先需要在 HTML 裏面加上支持 MQTT over WebSocket 的 JS 文件:

<script src="https://unpkg.com/[email protected]/dist/mqtt.min.js"></script>

然後連接到 Broker:

var client = mqtt.connect("ws://iot.eclipse.org/ws")

注意這裏 Broker 的 URL 中的協議部分變成了 “ws”。

在這裏我們沒有指定 Client Identifier,而 Client 庫或 Broker 會爲我們自動生成一個 Client Identifier。這樣打開多個 Web 訂閱端時,就不會發生衝突。但是這樣是無法使用持久化會話的,所以在實際項目中,你應該爲每一個 Web 訂閱端分配一個唯一 Client Identifier,比如把用戶 ID 作爲 Client Identifier 的一部分。

接下來訂閱相關主題:

client.subscribe("front_door/detection/objects", {
                qos: 1
            }, function (err) {
                if (err != undefined) {
                    console.log("subscribe failed")
                } else {
                    console.log(`subscribe succeeded`)
                }
            })

處理消息

上一課中講到,在接受消息的時候,我們需要對消息進行去重:

var receivedMessages = new Set();
client.on("message", function (_, payload) {
        var jsonMessage = JSON.parse(payload.toString())
        if(!receivedMessages.has(jsonMessage.id)){
            receivedMessages.add(jsonMessage.id)
            //接下來把結果顯示在頁面上面
        }
    })

爲了演示簡單,這裏使用了一個 Set 來保存已收到消息的 ID。實際項目中,可以用稍微複雜一點的數據結構,比如支持 Expiration 的緩存來存儲已收到消息的 ID。

然後把接收到的結果在頁面上顯示出來(這裏使用 Table 來顯示):

var date = new Date(jsonMessage.timestamp * 1000)
$('#results tr:last').after(`<tr><td>${date.toLocaleString()}</td><td>${jsonMessage.objects}</td><td><img src="${jsonMessage.image_url}" height="200"></td></tr>`);

Web 訂閱端的最終效果是這樣的:

小結

我們花了兩節課完成了一個 IoT+AI 的實戰項目,在這個框架下還可以繼續擴展新功能,比如將訓練好的新模型從雲端下發到設備端,以提升識別效率等。有興趣的讀者可以自行擴展。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章