###### tags: `JavaScript` `MQTT` # 在網頁中使用 JavaScript 進行 MQTT 通訊 MQTT 是非常輕便簡易的通訊協定, 由於大部分的 MQTT broker 都支援 websocket, 因此我們也可以在網頁中使用 MQTT, 以下以 [MQTT.js](https://github.com/mqttjs/MQTT.js) 這個模組為例, 並以 https://test.mosquitto.org/ 提供的 MQTT broker 示範: ```htmlmixed= <html> <head> <title>test Ws mqtt.js</title> <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script> </head> <body> <script> var client = mqtt.connect("ws://test.mosquitto.org:8080") // you add a ws:// url here client.on('connect', ()=>{ console.log('connected.'); client.subscribe("mee") client.on("message", function (topic, payload) { console.log(payload); console.log([topic, payload].join(": ")); // client.end() }); client.publish("mee", "hello"); }); </script> </body> </html> ``` - 第 4 行是 [MQTT.js 提供的 CDN](https://github.com/mqttjs/MQTT.js#browser), 你也可以儲存一份本機檔使用。 - 第 8 行就是以 websocket 連上 MQTT broker, 在 test.mosquitto.org 的頁面上有說明, 不加密、不認證的測試用 broker 使用 [8080 通訊埠](test.mosquitto.org)。 - 第 9 行就可以向 MQTT broker 訂閱頻道, 並且透過第 11 行註冊 `message` 事件的函式。 - 第 16 行則是在特定頻道發佈訊息。 ## 連接支援 wss 的 MQTT broker 在 https 的網頁中並不能使用未加密的 ws 協定連接 MQTT, 必須改用 wss 協定。我們測試的 test.mosquitto.org 網站也提供 wss 協定, 但要改用 8081 埠: ```htmlmixed= var client = mqtt.connect("wss://test.mosquitto.org:8081"); client.on('connect', ()=>{ console.log('connected.'); client.subscribe("mee") client.on("message", function (topic, payload) { console.log(payload); console.log([topic, payload].join(": ")); // client.end() }); client.publish("mee", "hello"); }); ``` 可以用 [p5.js Web Editor](https://editor.p5js.org/codemee/sketches/4RjXx5qwz) 測試。 ## 連接需要帳號密碼登入的 MQTT broker 如果 MQTT broker 需要帳密登入, 也可以在連接時加上 options 物件指定使用者名稱與密碼。在我們測試用的 test.mosquitto.org 提供有 rw/readwrite 帳密可供測試: ```htmlmixed= let options = { username: 'rw', // 可讀寫的測試帳戶 password: 'readwrite' // 測試帳戶的密碼 } var client = mqtt.connect( // test.mosquitto.org 的 wss 使用 8081 埠 "wss://test.mosquitto.org:8081", options // 連接時指定選項登入 ); client.on('connect', ()=>{ console.log('connected.'); client.subscribe("mee") client.on("message", function (topic, payload) { console.log(payload); console.log([topic, payload].join(": ")); // client.end() }); client.publish("mee", "hello"); }); ``` 可以用 [p5.js Web Editor](https://editor.p5js.org/codemee/sketches/745HI130Z) 測試。 ## AIO MQTT broker Adafruit IO 的 wss 走 443 埠, 密碼要使用金鑰, 不是登入的密碼, 頻道的完整名稱都是『使用者名稱/feeds/feed名稱』: ```htmlmixed= let options = { username: 'meebox', // AIO 使用者名稱 password: 'aio_aFyj218T7BBUvc6WEhPiSjjbaevf' // AIO 金鑰 } client = mqtt.connect( // AIO mqtt websocket 走 443 埠 "wss://io.adafruit.com:443", options // 連接時指定選項登入 AIO ); console.log('connnecting....'); client.on('connect', ()=>{ console.log('connected.'); client.subscribe("meebox/feeds/rain") // 我建立的 feed client.on("message", function (topic, payload) { console.log(payload); console.log([topic, payload].join(": ")); // client.end() }); client.publish("meebox/feeds/rain", "hello"); }); ``` 可以用 [p5.js Web Editor](https://editor.p5js.org/codemee/sketches/_cCXzIoXJ) 測試。 ## API 說明 詳細的 [API](https://github.com/mqttjs/MQTT.js#api) 可在網站上查詢。