使用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;</code></pre>

    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&gt;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 &lt; topics.length;i++){
                var topic = topics[i];
                html += topic.Describe;
                html += '<input type="checkbox" value="'+topic.Topic+'">';
            }
            $("#subTopics").html(html);
        }
    
        //绑定发布主题
        function BindPubTopics(topics) {
            var html = "";
            for (var i = 0; i &lt; topics.length; i++) {
                var topic = topics[i];
                html += '<option value="' + topic.Topic + '">' + topic.Describe + '</option>';
            }
            $("#pubTopics").html(html);
        }</code></pre>

    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);
        }</code></pre>

    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");
            }
        }</code></pre>

    注意: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