--
前言
之前一直使用 MQTT.js,後來出現了「WebSocket connection to 'ws://xxx/mqtt' failed: Close received after close」錯誤,雖然會自動重連,不過就要處理重連初始化的訊息。可以處理不過在 google 追究之後,就決定改用 Paho MQTT 試試看,畢竟在 Python 也是使用 Paho MQTT 的版本,說不定可以解決問題
--
參考資源
- Paho JavaScript - MQTT Client Library Encyclopedia (hivemq.com)
- Eclipse Paho | The Eclipse Foundation
Paho MQTT JavaScript 1.0.3 版本截至 2024/07 只支援 3.1.1,對於網頁 WebSocket 而言並不影響
--
程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<!DOCTYPE html> <html lang="zh-TW"> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <title>Paho MQTT JS Test</title> <link href="https://cdn.jsdelivr.net/npm/fastbootstrap@2.2.0/dist/css/fastbootstrap.min.css" rel="stylesheet"> <script src="https://cdn.jsdelivr.net/npm/paho-mqtt@1.0.3/mqttws31-min.js"></script> </head> <body> <button type="button" class="btn btn-light" onclick="send()">Send</button> <script src="php.js?v=65cd879be1395"></script> <script> let mc; let mqtt_client_id = window.localStorage.client_id + '_' + Math.random().toString(16); mc = new Paho.MQTT.Client("broker.hivemq.com", 8884, mqtt_client_id); mc.connect({ onSuccess: onConnect, useSSL: true }); // set callback handlers mc.onConnectionLost = function (responseObject) { console.log(responseObject.errorCode); console.log("Connection Lost: "+responseObject.errorMessage); } mc.onMessageArrived = function (message) { console.log(message.payloadString); } // Called when the connection is made function onConnect(){ console.log("Connected!"); mc.subscribe("HootKaSelf/lobby", { onSuccess: function (){ console.log('subscribeSuccess'); }, onFailure: function (){} }); let message = new Paho.MQTT.Message("Hello"); message.destinationName = "HootKaSelf/lobby"; mc.send(message); } function send(){ let message = new Paho.MQTT.Message(JSON.stringify({ command: "question", room_id: window.localStorage.in_room, order: '大家好', })); console.log(message); message.destinationName = "HootKaSelf/lobby"; mc.send(message); } </script> </body> </html> |
--
安裝、連接
安裝使用 CDN,MQTT Broker 使用了 HiveMQ 的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<script src="https://cdn.jsdelivr.net/npm/paho-mqtt@1.0.3/mqttws31-min.js"></script> <script> mc = new Paho.MQTT.Client('broker.hivemq.com', 8884, 'mqtt_client_id'); mc.connect({ onSuccess: onConnect, useSSL: true, }); function onConnect(){ // 連接成功訂閱主題 mc.subscribe("HootKaSelf/lobby", { onSuccess: function (){ console.log('subscribeSuccess'); }, onFailure: function (){} }); } </script> |
.connect() 選項
- timeout:"number"
- userName:"string"
- password:"string"
- willMessage:"object"
- keepAliveInterval:"number"
- cleanSession:"boolean"
- useSSL:"boolean"
- invocationContext:"object"
- onSuccess:"function"
- onFailure:"function"
- hosts:"object"
- ports:"object"
- mqttVersion:"number"
- mqttVersionExplicit:"boolean"
- uris: "object"
如果 Broker 需要帳號、密碼,就需要增加 userName password 選項
--
訂閱、取消訂閱主題
訂閱主題
1 2 3 4 5 6 |
mc.subscribe("HootKaSelf/lobby", { onSuccess: function (){ console.log('subscribeSuccess'); }, onFailure: function (){} }); |
取消訂閱主題
1 2 3 4 5 6 |
mc.unsubscribe('HootKaSelf/room/' + j['room_id'], { onFailure: function () {}, onSuccess: function () { console.log("subscribe success!"); } }); |
--
傳送訊息
使用 JSON 格式
1 2 3 4 5 6 7 |
let message = new Paho.MQTT.Message(JSON.stringify({ command: "start_game", room_id: room_id, user_id: client_id, })); message.destinationName = "HootKaSelf/server"; mc.send(message); |
--
接收訊息
1 2 3 |
mc.onMessageArrived = function (message) { let json = JSON.parse(message.payloadString); } |
接收的訊息經過處理轉換成 JSON 格式
messge 可接收到
- destinationName 主題
- duplicate 是否為重複發送
- payloadBytes 字數
- payloadString 內容
- qos
- retained
--
AMQJS0005E Internal error.
Paho MQTT 出現這個錯誤的話是 onMessageArrived 接收訊息處理時程式有錯誤,導致 WebSocket 斷線,這時 Paho 會攔截錯誤加上自己的資訊。所以會讓人誤會是 MQTT 連接問題,其實只是接受訊息內的程式出錯。
--
結論
Paho MQTT 確實解決了 MQTT.js 的問題,Paho MQTT 的心跳保持功能比較正常,一天的測試之下都是維持同一個連接,並不會重新連接。反之 MQTT.js 則是多次重新連接,不知道原因為何。
最後 (2024/07) Hoyo 推薦 JavaScript 使用 Paho MQTT
--
941 total views, 1 views today