[Web前端]使用paho MQTT.javascript来连接百度IOT(天工物接入)

标题[Web前端]使用paho MQTT.javascript来连接百度IOT(天工物接入)

    对于MQTT相信搞物联网的话,已经不是很陌生了。MQTT是基于TCP长连接下的,它的报文比较小,非常适合于物联网嵌入式设备使用。对于详细的MQTT协议可以参考网上其他文章,这里推荐一个github上的中文协议手册

MQTT协议中文版 : https://mcxiaoke.gitbooks.io/mqtt-cn/content/

在项目开发中,嵌入式端已经实现了MQTT对接百度天工物联(后期再写一篇paho.mqtt.embedded-c的移植教程),但是苦于没有一个web端控制。在网上也寻找过方案,包括用后端PHPMQTT实现,ASP.net也有对于的MQTT库。但是没有一个简单的快速实现方法,如果会一点html+javascript的话,我再想,是不是能用前端的技术来实现一个简单的MQTT。按这个思路去网上搜寻,还真有相关的库。

1 - MQTT.js

https://www.npmjs.com/package/mqtt

MQTT.js is a client library for the MQTT protocol, written in JavaScript for node.js and the browser.

2 - Paho

http://www.eclipse.org/paho/downloads.php

Paho的库做的比较全,支持一下语言。

上表中看到,Paho有一个JavaScript的支持,居然我前面的STM32开发板中用的是Paho的Embedded版本移植,那就想尝试下Paho的JavaScript吧,好在前几年也自学过一些javascript语法。

在网上找了下,关于Paho MQTT.js去对接百度天工物联的资料比较少,索性将自己的摸索过程记录下来。

MQTT系统结构
本文的目的是 实现通过网页实时控制设备端的一个LED灯。

本文主要讲述的内容是在已实现物联网设备的基础上,设计web页面实现网页和嵌入式物联网设备的数据通讯。整个系统结构如下:



 设备端启动后,连接百度IOT服务器,并订阅一个主题【mytopic01】。web页面端启动后,根据用户设置的百度IOt的账号密码进行连接,并在页面中添加2个button,用于推送主题消息。

开源库列表
1-paho.mqtt.javascript : https://github.com/eclipse/paho.mqtt.javascript

2-相关文档 : http://www.eclipse.org/paho/files/jsdoc/index.html

html页面设计
这里只讲究功能,页面的美化就不考虑了,有能力的同学可以用Bootstrap对页面进行精心排版和美化

新建 index.html

<!doctype html>
<html lang="en">
 
<head>
    <title>Paho MQTT.js </title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
 
    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B"
        crossorigin="anonymous">
 
    <!-- 引用MQTTCDN -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
 
</head>
 
<body>
 
    <div class="container">
        <div class="row">
            <div class="col">
            </div>
            <h1>Paho MQTT.js Test!</h1>
            <div class="col">
            </div>
        </div>
        <div class="row">
            <div class="col-md">
 
            </div>
            <div class="col-md-5">
                <div class="card border-success">
                    <div class="card-img-top"><img class="" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1534998931421&di=9c27aaeef01a83dd530a40f7b06aae1f&imgtype=0&src=http%3A%2F%2Fpic.58pic.com%2F58pic%2F15%2F53%2F67%2F93a58PICrhF_1024.png"
                            width="50px" height="50px" alt=""></div>
 
                    <div class="card-body">
                        <h4 class="card-title">LED control</h4>
                        <p class="card-text">
                            <button type="button" class="btn btn-primary" οnclick='publish("ON");'>开灯</button>
                            <button type="button" class="btn btn-seconday" οnclick='publish("OFF");'>关灯</button>
                        </p>
                    </div>
                </div>
            </div>
            <div class="col-md">
 
            </div>
 
        </div>
    </div>
 
    <!-- 相关业务代码 -->
    <script src="utility_paho.js"></script>
 
</body>
 
</html>

这是一个简单的HTML页面,添加了2个Button。关于MQTT 通信的相关代码在 utility_paho.js 文件内。

JS代码设计
新建 utility_paho.js 文件


```javascript
var passWord = "baidu IOT 的设备实例密码";
var username = "设备实例用户名";
var hostname = "XXXXX.mqtt.iot.gz.baidubce.com";  //替换成的你百度实例地址
var port = "8884";    //使用WSS协议的接口地址
var clientId = makeid();
 
var connected = false;
 
var client = new Paho.MQTT.Client(hostname, Number(port), "/mqtt", clientId);
 
logMessage("INFO", "Connecting to Server: [Host: ", hostname, ", Port: ", port, ", Path: ", client.path, ", ID: ", clientId, "]");
 
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
//  client.onConnected = onConnected;
 
var options = {
    invocationContext: { host: hostname, port: port, clientId: clientId },
    timeout: 5,
    keepAliveInterval: 60,
    cleanSession: true,
    useSSL: true,
    //reconnect: true,
    onSuccess: onConnect,
    onFailure: onFail,
    mqttVersion: 4
};
 
options.userName = username;
options.password = passWord;
 
client.connect(options);
 
function subscribe() {
    var topic = "mytopic01";
    var qos = 0;
    logMessage("INFO", "Subscribing to: [Topic: ", topic, ", QoS: ", qos, "]");
    client.subscribe(topic, { qos: Number(qos) });
}
 
 
function publish(ledState) {
    var topic = "mytopic01";
    var qos = 0;
    var message = ledState;
    var retain = false;
 
    message = "{\"LED\":\"" + message + "\"} ";
 
    logMessage("INFO", "Publishing Message: [Topic: ", topic, ", Payload: ", message, ", QoS: ", qos, ", Retain: ", retain, "]");
    message = new Paho.MQTT.Message(message);
    message.destinationName = topic;
    message.qos = Number(qos);
    message.retained = retain;
    client.send(message);
}
 
 
function disconnect() {
    logMessage("INFO", "Disconnecting from Server.");
    client.disconnect();
}
 
 
 
 
 
// called when the client loses its connection
function onConnectionLost(responseObject) {
    if (responseObject.errorCode !== 0) {
        logMessage("INFO", "Connection Lost. [Error Message: ", responseObject.errorMessage, "]");
    }
    connected = false;
}
 
// called when a message arrives
function onMessageArrived(message) {
    logMessage("INFO", "Message Recieved: [Topic: ", message.destinationName, ", Payload: ", message.payloadString, ", QoS: ", message.qos, ", Retained: ", message.retained, ", Duplicate: ", message.duplicate, "]");
    
}
 
 
 
// called when the client connects
function onConnect(context) {
    // Once a connection has been made, make a subscription and send a message.
    var connectionString = context.invocationContext.host + ":" + context.invocationContext.port + context.invocationContext.path;
    logMessage("INFO", "Connection Success ", "[URI: ", connectionString, ", ID: ", context.invocationContext.clientId, "]");
 
    connected = true;
 
}
 
 
function onConnected(reconnect, uri) {
    // Once a connection has been made, make a subscription and send a message.
    logMessage("INFO", "Client Has now connected: [Reconnected: ", reconnect, ", URI: ", uri, "]");
    connected = true;
 
}
 
function onFail(context) {
    logMessage("ERROR", "Failed to connect. [Error Message: ", context.errorMessage, "]");
 
    connected = false;
 
}
 
 
function makeid() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
 
    for (var i = 0; i < 15; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));
 
    return text;
}
 
 
 
function logMessage(type, ...content) {
 
    var date = new Date();
    var timeString = date.toUTCString();
    var logMessage = timeString + " - " + type + " - " + content.join("");
 
    if (type === "INFO") {
        console.info(logMessage);
    } else if (type === "ERROR") {
        console.error(logMessage);
    } else {
        console.log(logMessage);
    }
}

 
 
对于Paho 相关API接口函数的使用,可以参考以上相关文档说明

运行页面
将以上的 index.html 和 utility_paho.js 放在同一目录下,`在这里插入代码片`使用浏览器(推荐chrome)打开index.html即可看到画面.



 

对于百度天工物联的实例添加和设置,请自行百度学习。

几个坑点
在实验过程中,本人也掉过接个坑,现总结下。

1. client.connect(options); 方法的 options参数名称必须要和文档中正确,不能有多余货错误参数,否者会出现如下错误:



2. paho javascript版本是使用WS协议通信的,所有不能使用百度天工的tcp端口了。使用如下图片中的第三个,并使用SSL (useSSL : true)  

这一点也要感谢 QQ群好友 明宝(23072790XX) 的提醒,对于一个搞嵌入式硬件的,一开始还真不知道paho 的javascript 版本使用的ws协议接口,一直在1883端口下试来试去一直报错。




```javascript
var options = {
    invocationContext: { host: hostname, port: port, clientId: clientId },
    timeout: 5,
    keepAliveInterval: 60,
    cleanSession: true,
    useSSL: true,
    onSuccess: onConnect,
    onFailure: onFail,
    mqttVersion: 4
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值