MQTT学习(三)--使用paho-mqtt和JQuery创建MQTT客户端

在之前的两篇文章中分解介绍了如何搭建MQTT服务器和MQTT桌面客户端,为了更好的体现MQTT多平台适应性,本篇文章将来说明如何使用paho-mqtt.js和JQuery.js来创建一个Web版的MQTT客户端。
在具体的需求上,仍与上篇中的WPF版MQTT客户端的需求保持一致。下面将直接说明实现过程。

MQTT学习(二)–使用MQTTNet在WPF框架下搭建MQTT客户端


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

目前常见的关于MQTT协议的JavaScript库有MQTT.js、paho-mqtt.js等,其中MQTT.js是需要Node.js的相关环境的,因为本人计算机上暂时没有Node.js环境,所以这个示例选用paho-mqtt.js来实现。paho-mqtt.js的源码可以在GitHub上找到。

paho.mqtt.javascript

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

<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>

考虑到有时需要在非互联网情况下开发测试,所以也可以将文件下载下来从本地引入。paho-mqtt.js可以从GitHub库里下载到本地。
JQuery.js是经常用到的库了。如何引入和使用方法就不再多做介绍了。对于这两个库我都是下载到本地项目引入的。

2.页面布局

页面布局和上一篇中的WPF版客户端基本保持一致,代码如下:


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>title>
	<meta charset="utf-8" />
    <script src="Scripts/jquery.min.js">script>
    <script src="Scripts/paho-mqtt.js">script>
head>
<body>
    <table>
        <tr>
            <td>td>
            <td><input id="txtIp" type="text" value="127.0.0.1"/>td>
            <td><input id="txtPort" type="text" value="61623"/>td>
            <td><input id="btnConnect" type="button" value="连接"/>td>
            <td><input id="btnDisconnect" type="button" value="断开" disabled="disabled"/>td>
            <td>td>
        tr>
        <tr>
            <td>td>
            <td colspan="3">
                <div id="subTopics">
                div>
            td>
            <td><input id="btnSubscribe" type="button" value="订阅" disabled="disabled"/>td>
            <td>td>
        tr>
        <tr>
            <td>td>
            <td colspan="4">
                <ul id="logResult">ul>
            td>
            <td>td>
        tr>
        <tr>
            <td>td>
            <td>
                <select id="pubTopics">
                select>
            td>
            <td colspan="2"><input id="txtContent" type="text"/>td>
            <td><input id="btnPublish" type="button" value="发布" disabled="disabled"/>td>
            <td>td>
        tr>
    table>
body>
html>
    

呈现效果如下:
MQTT学习(三)--使用paho-mqtt和JQuery创建MQTT客户端_第1张图片

3.数据结构

同之前的桌面版客户端一样,我在JS脚本中定义了几个简单的数据结构。

        //所有主题
        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 += '+topic.Topic+'"/>';
            }
            $("#subTopics").html(html);
        }

        //绑定发布主题
        function BindPubTopics(topics) {
            var html = "";
            for (var i = 0; i < topics.length; i++) {
                var topic = topics[i];
                html += ' topic.Topic + '">' + topic.Describe + '';
            }
            $("#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"); } }

    7.测试实例

    代码编写完成后,启动运行来测试一下实际效果。启动Apollo并打开管理界面,分别打开三个Web客户端页面,并输入IP地址和端口,然后连接服务端。

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

    在服务端的管理界面,可以看到Connectors选项卡中的ws分组下有三个连接。说明连接成功,客户端运行正常。选择主题订阅、发布,数据的收发也都正常。
    MQTT学习(三)--使用paho-mqtt和JQuery创建MQTT客户端_第2张图片

    接下来再打开一个WPF版的客户端,连接服务端,订阅、收发消息也都正常。
    MQTT学习(三)--使用paho-mqtt和JQuery创建MQTT客户端_第3张图片

    经过上面的测试说明桌面客户端和Web客户端可以无缝连接,相互通信了。后续将考虑采用更多不同形式的终端来实现信息互通。


    实践出真知。

    源代码地址

    你可能感兴趣的:(Web,MQTT,MQTT学习实践)