使用paho-mqtt和JQuery创建MQTT客户端

1.引入paho-mqtt.js和JQuery.js

目前常见的关于MQTT协议的JavaScript库有MQTT.js、paho-mqtt.js等,其中MQTT.js是需要Node.js的相关环境的

paho-mqtt.js的引入可以使用网络地址引入

http://cdn.bootcss.com/paho-mqtt/1.1.0/paho-mqtt.min.js

考虑到有时需要在非互联网情况下开发测试,所以也可以将文件下载下来从本地引入。paho-mqtt.js可以从GitHub库里下载到本地。 JQuery.js是经常用到的库了。

2.页面布局

代码如下:

    

    呈现效果如下:

    3.数据结构

    //所有主题
    var allTopics = [
                { "Topic": "/data/alarm", "Describe": "报警" },
                { "Topic": "/data/message", "Describe": "消息" },
                { "Topic": "/data/notify", "Describe": "通知" }
            ];
    
            //选中订阅主题
            var selectedTopics = [];
    
            //选中发布主题
            var currentTopic;
    
            //客户端选项
            var option = {
                "ServerUri": "127.0.0.1",
                "ServerPort": 61623,
                "UserName": "admin",
                "Password": "password",
                "ClientId": "",
                "TimeOut": 5,
                "KeepAlive": 100,
                "CleanSession": false,
                "SSL":false
            }
    
            //客户端
            var client;

    4.数据初始化

    数据初始化包括了订阅主题和发布主题的绑定,以及选择订阅主题和选择发布主题的事件。

            $(function () {
                BindSubTopics(allTopics);
                BindPubTopics(allTopics);
    
                //订阅主题选中事件
                $("#subTopics input[type=checkbox]").on("click", function () {
                    var t = $(this).val();
                    var topic;
                    for(var i in allTopics){
                        var tmp = allTopics[i];
                        if (tmp.Topic == t) {
                            topic = tmp;
                        }
                    }
                    if ($(this).is(":checked")) {//选中
                        selectedTopics.push(topic);
                    }
                    else {//取消选择
                        if(selectedTopics.length>0){
                            for(var i in selectedTopics){
                                var tmp = selectedTopics[i];
                                if (tmp.Topic == t) {
                                    selectedTopics.splice(i, 1);
                                }
                            }
                        }
                    }
                });
    
                //发布主题选中事件
                $("#pubTopics").on("change", function () {
                    var d = $("#pubTopics option:selected").text();
                    var t = $("#pubTopics").val();
                    currentTopic = { "Topic": t, "Describe": d }
                    console.log(currentTopic);
                });
    
                //订阅按钮点击事件
                $("#btnSubscribe").on("click", function () {
                    if (!client) {
                        alert("请连接服务端");
                        return;
                    }
                    if(selectedTopics.length==0){
                        alert("请选择要订阅的主题!");
                        return;
                    }
    
                    var msg = "";
                    for(var i in selectedTopics){
                        var t = selectedTopics[i];
                        client.subscribe(t.Topic);
                        msg+=t.Topic+";"
                    }
                    WriteToStatus("成功订阅主题:" + msg);
                });
    
                //发布按钮点击事件
                $("#btnPublish").on("click", function () {
                    if(!client){
                        alert("请连接服务端");
                        return;
                    }
                    if (!currentTopic) {
                        alert("请选择要发布的主题!");
                        return;
                    }
                    if($("#txtContent").val()==""){
                        alert("请输入要发布的内容");
                        return;
                    }
    
                    var message = new Paho.Message($("#txtContent").val());
                    message.destinationName = currentTopic.Topic;
                    client.send(message);
    
                    WriteToStatus("发布了主题为" + currentTopic.Topic + "的消息:" + $("#txtContent").val())
                });
            });
    
            //绑定订阅主题
            function BindSubTopics(topics) {
                var html = "";
                for (var i = 0; i < topics.length;i++){
                    var topic = topics[i];
                    html += topic.Describe;
                    html += '';
                }
                $("#subTopics").html(html);
            }
    
            //绑定发布主题
            function BindPubTopics(topics) {
                var html = "";
                for (var i = 0; i < topics.length; i++) {
                    var topic = topics[i];
                    html += '';
                }
                $("#pubTopics").html(html);
            }

    5.MQTT事件

     $(function () {
    
                //连接按钮点击事件
                $("#btnConnect").on("click", function () {
                    if ($("#txtIp").val()!="") {
                        option.ServerUri = $("#txtIp").val();
                    }
                    else {
                        alert("请输入服务端IP!");
                        return;
                    }
    
                    if($("#txtPort").val()!=""){
                        option.ServerPort = Number($("#txtPort").val());
                    }
                    else {
                        alert("请输入端口号!");
                        return;
                    }
                    //设置客户端标识
                    option.ClientId = guid();
                    //客户端实例化
                    client = new Paho.Client(option.ServerUri, option.ServerPort, option.ClientId)
                    client.onConnectionLost = onConnectionLost;//绑定连接断开事件
                    client.onMessageArrived = onMessageArrived;//绑定接收消息事件
                    //连接服务端
                    client.connect({
                        invocationContext: {
                            host: option.ServerUri,//IP地址
                            port: option.ServerPort,//端口号
                            path: client.path,
                            clientId: option.ClientId//标识
                        },
                        timeout: option.TimeOut,//连接超时时间
                        keepAliveInterval: option.KeepAlive,//心跳间隔
                        cleanSession: option.CleanSession,//是否清理Session
                        useSSL: option.SSL,//是否启用SSL
                        userName: option.UserName,  //用户名
                        password: option.Password,  //密码
                        onSuccess: onConnect,//连接成功回调事件
                        onFailure: onError//连接失败回调事件
                    });
    
                });
    
                //断开按钮点击事件
                $("#btnDisconnect").on("click", function () {
                    client = null;
    
                    enable($("#btnConnect"), true);
                    enable($("#btnDisconnect"), false);
                    enable($("#btnPublish"), false);
                    enable($("#btnSubscribe"), false);
                });
            });
    
            //连接成功回调事件
            function onConnect() {
                WriteToStatus("连接成功!")
    
                enable($("#btnConnect"), false);
                enable($("#btnDisconnect"), true);
                enable($("#btnPublish"), true);
                enable($("#btnSubscribe"), true);
            }
            //连接失败回调事件
            function onError(e) {
                WriteToStatus("连接失败:" + e)
    
                enable($("#btnConnect"), true);
                enable($("#btnDisconnect"), false);
                enable($("#btnPublish"), false);
                enable($("#btnSubscribe"), false);
            }
            //连接断开事件
            function onConnectionLost(e) {
                if (e.errorCode !== 0) {
                    WriteToStatus("连接异常断开:" + e.errorMessage);
    
                    enable($("#btnConnect"), true);
                    enable($("#btnDisconnect"), false);
                    enable($("#btnPublish"), false);
                    enable($("#btnSubscribe"), false);
                }
            }
            //接收消息事件
            function onMessageArrived(data) {
                WriteToStatus("收到消息:" + data.payloadString);
            }

    6.相关辅助方法

     //状态输出
            function WriteToStatus(data) {
                var now = new Date();
                var message = '[' + now.toLocaleTimeString() + ']' + data;
                console.log(message);
                $("#logResult").append('
  • ' + message + '
  • '); } //生成GUID function guid() { function S4() { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1); } return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4()); } //切换按钮状态 function enable(button,enabled) { if (enabled) { button.removeAttr("disabled"); } else { button.attr("disabled", "disabled"); } }

    注意:paho-mqtt.js默认使用的是WebSocket连接,所以端口号应使用配置中ws对应的端口号,而非tcp对应的端口号。

    7.测试实例

    在线服务器

    • 地址: mqtt.p2hp.com
    • 端口:1883 (TCP), 8083 (WebSocket)
    • 类型:EMQ
    • MQTT V3.1.1/V5.0 兼容
    • 免费使用
    • 状态
    联系我们

    邮箱 626512443@qq.com
    电话 18611320371(微信)
    QQ群 235681453

    Copyright © 2015-2024

    备案号:京ICP备15003423号-3