不知道你的家中是否有 IoT(Internet of Thing,物聯網)的裝置?例如一顆智慧燈泡,只要手機下載控制的 App,就能在外面就控制燈泡的開關,甚至色彩及明暗。
然而,一般家庭的網路環境通常都是電信公司的數據機,再搭配簡易的路由器,因而在家裡內部的網路裝置都會被擋在 NAT 後方,導致手機沒辦法找到燈泡。
*外網設備主動連到內網設備,會有 NAT 的問題
這時問題就來了,手機想要控制時,如何透過在外網的伺服器主動發送訊息給內網中的智慧燈泡?
我們之前在聊 NAT 的時候有討論到一些解決方案,例如 Port Forwarding、Hole Punching 及 ICE 等等,但是前兩者會受限於 Router 的設定及 NAT 型態,而 ICE 需要的架構又有些太 Heavy 了點。
那麼,是否可以讓智慧燈泡主動去找伺服器呢?答案是肯定的。
我們可以每隔一段時間就請燈泡著動發送訊息給伺服器,然後當手機傳送訊號到伺服器後,燈泡再發送訊息時得到的回應就會包含手機想要做的指令,而這種機制就稱作 Polling(輪詢)。但是 Polling 的缺點就是 Overhead 比較大,會增加伺服器的負荷。
於是就有一種新的資料傳輸模式 Pub-Sub Pattern(發布/訂閱模式)的出現。
所謂的 Pub-Sub 就是 Publish(發布)和 Subscribe(訂閱)的意思,發佈消息的稱為發布者(Publisher)而理所當然的訂閱消息的就是訂閱者(Subscriber)。
而大多數的 Pub-Sub 系統都會有一個中心的 Component,稱作 Broker(中介)。發布者會發送訊息到 Broker,而訂閱者則會隨時和 Broker 保持聯繫,一旦有新的訊息出現,訂閱者就能及時拿到。
*Pub-Sub Pattern 及 Broker,控制智慧燈泡範例
訂閱者可以選擇某個 Topic(主題)訂閱,例如隨意命名的 bedroom/lightbulb/switch
這個 Topic 讓智慧燈泡去訂閱便能收到開或關的指令。
因此,只要家中的智慧燈泡和雲上的 Broker 實時保持聯繫,就能收到發布者送出的訊息。家中的智慧燈泡不只一個,也可以讓多個燈泡同時訂閱同一個主題,就能簡單一次開關多個燈泡的行為了。
來到這次要講的主題,全名為「訊息佇列遙測傳輸(Message Queuing Telemetry Transport)」的 MQTT。其基本組成就是 Broker 和 Client,Client 又包含 Publisher 及 Subscriber 來和 Broker 發布或是訂閱訊息。
而 MQTT 這個協定就實作上述所說的 Pub-Sub Pattern,是一個基於 TCP 的應用層協定,主打輕量級,因此很適合 IoT 裝置的使用。
之所以是輕量級,是因為 MQTT 的 Header 相較其他應用層的 Header 小了許多。例如 HTTP Header 最小需要大約 30 Bytes,一般一個 HTTP GET Request 會用到幾百 Bytes 到 1, 2 KB 左右;而 MQTT Header 最小只用了 2 Bytes,一般來說會用到幾十 Bytes 到幾百 Bytes,大約比 HTTP 小了一個數量級。
其他更多的 MQTT 細節,像是如何保持連線這回事,我們下一講繼續聊。