实现网页版MQTT

一、目录结构

1、目录结构

在这里插入图片描述

二、代码

css/index.css

*{
    padding: 0;
    margin: 0;
}
.left{
    float: left;
}
.right{
    float: right;
}
textarea{
    resize: none;
  }
#box{
    overflow: hidden;
    width: 775px;
    height: 720px;
    /* border: 1px solid black; */
    margin: 0 auto;
    padding: 30px 0 0 20px;
    box-sizing: border-box;
    background: #eee;
}
/* 连接配置开始 */
.disposition{
    padding: 10px;
    width: 430px;
    height: 470px;
    border: 1px solid #ccc;
    box-sizing: border-box;
    position: relative;
    border-right: none;
}
.disposition li{
    width: 430px;
    list-style: none;
    line-height: 60px;
    font-size: 20px;
    position: relative;
}
.disposition li input{
    width: 260px;
    height: 30px;
    position: absolute;
    right: 40px;
    top: 13px;
}
.disposition li:nth-of-type(2) input{
    width: 30px;
    height: 30px;
    position: absolute;
    right: 275px;
    top: 13px;
}
.disposition  .special{
    position: absolute;
    bottom: -7px;
    left: 10px;
}
.disposition  .special .connect{
    color: red;
}
.disposition button{
    width: 80px;
    height: 40px;
    position: absolute;
    right: 40px;
}
/* 连接配置结束 */
/* 发送数据开始 */
.sendData{
    position: relative;
    padding: 10px 10px 10px 30px;
    width: 304px;
    height: 470px;
    border: 1px solid #ccc;
    box-sizing: border-box;
    /* height: 440px; */
    /* background: skyblue; */
}
.sendData .top textarea{
    margin-top: 13px;
}
.sendData .top button{
    width: 80px;
    height: 40px;
    margin: 10px 11px;
}
.sendData .top button:nth-child(4){
    position: absolute;
    right: 10px;
}
.sendData .bottom button{
    width: 80px;
    height: 40px;
    position: absolute;
    right: 20px;
    bottom: 12px;
}
/* 发送数据结束 */
/* 接收数据开始 */
.receiveData{
    position: relative;
    border: 1px solid #ccc;
    width: 734px;
    padding: 10px;
    box-sizing: border-box;
    border-top: none;
    /* height: 170px; */
    /* background: red; */
    /* margin-top: 10px; */
}
.receiveData button{
    position: absolute;
    width: 40px;
    height: 80px;
    margin-top: 40px;
    right: 20px;
}
.receiveData textarea{
    margin-top: 10px;
    overflow: auto;
}
/* 接收数据结束 */

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="css/index.css">
     <script src="js/paho-mqtt.js"></script>
    <title>mqtt助手</title>
</head>
<body>
    <div id="box">
        <!-- 连接配置开始 -->
        <div class="disposition left"">
            <ul>
                <h3>连接配置</h3>
                <li>IP地址:<input class="address" type="text" value="ws://mnif.cn:8083/mqtt"></li>
                <!-- <li>端口号:<input class="port" type="text" value="8083"></li> -->
                <li>useSSL:<input class="ssl" type="checkBox"></li>
                <li>ClientID:<input class="clientId" type="text"></li>
                <li>用户名:<input class="username" type="text" value="yang"></li>
                <li>密码:<input class="psd" type="text" value="11223344"></li>
                <li>发布的主题:<input class="issueTopic" value="yang" type="text"></li>
                <li class="special">
                    <span>连接状态:</span>
                    <span class="connect">连接断开</span>
                    <button class="connectBtn right">连接</button>
                </li>
            </ul>
        </div>
        <!-- 连接配置结束 -->
        <!-- 数据发送开始 -->
        <div class="sendData left">
            <h3>数据发送</h3>
            <div class="top">
                <textarea class="sendDataArea" name="" id="" cols="33" rows="10"></textarea>
                <input class="checkBox" type="checkbox">hex
                <button class="sendBtn">发送数据</button>
                <button class="clearSendData">清除</button>
            </div>
            <div class="bottom">
                <textarea class="bottomArea" name="" id="" cols="33" rows="10"></textarea>
                <button class="subscription">订阅</button>
            </div>
        </div>
        <!-- 数据发送结束 -->
        <!-- 数据接收开始 -->
        <div class="receiveData left">
            <h3>数据接收</h3>
            <textarea class="receiveArea" class="left" name="" id="" cols="85" rows="10"></textarea>
            <button class="right receiveClear">清除</button>
        </div>
        <!-- 数据接收结束 -->
    </div>

    <script>
        let address = document.getElementsByClassName('address')[0];//
        let ssl = document.getElementsByClassName('ssl')[0];
        let clientId = document.getElementsByClassName('clientId')[0];
        let connectBtn = document.getElementsByClassName('connectBtn')[0];
        let username = document.getElementsByClassName('username')[0];
        let password = document.getElementsByClassName('psd')[0];
        let connect = document.getElementsByClassName('connect')[0];
        let receiveArea = document.getElementsByClassName('receiveArea')[0];
        let receiveClear = document.getElementsByClassName('receiveClear')[0];
        let bottomArea = document.getElementsByClassName('bottomArea')[0];
        let subscription = document.getElementsByClassName('subscription')[0];
        let sendBtn = document.getElementsByClassName('sendBtn')[0];
        let sendDataArea = document.getElementsByClassName('sendDataArea')[0];
        let issueTopic = document.getElementsByClassName('issueTopic')[0];
        let clearSendData = document.getElementsByClassName('clearSendData')[0];
        let checkBox = document.getElementsByClassName('checkBox')[0];
        let client;
        let topic;
        let options = {//MQTT配置
            timeout:5,//链接超时时间5S
            cleanSession: true,
            useSSL: false,
            userName: "yang",  
            password: "11223344",  
            onSuccess: onSuccess,
            onFailure: onFailure,
            keepAliveInterval: 30,
        };


        
        // 监听连接按钮点击
        connectBtn.onclick = function(){
            // 监听ssl的状态变化
            if(ssl.checked == true){
                options.useSSL = true;
                // console.log(1);
            }else{
                options.useSSL = false;
                // console.log(2);
            }
            let oAddress = address.value;
            // let oAport = port.value;
            let oClientId = clientId.value;
            if(connectBtn.textContent == '连接'){
                if(oClientId.length == 0){
                    oClientId = (+new Date())+ '' + parseInt(Math.random() * 10000000000000000) ; //时间戳加16位随机数
                }
                client = new Paho.MQTT.Client(oAddress, oClientId);
                options.userName = username.value || 'yang';
                options.password = password.value || '11223344';

                client.onConnectionLost = onFailure;//连接丢失回调
                client.onMessageArrived = onMessageArrived;//设置接收数据回调

                client.connect(options);//成功连接执行onConnect函数
            }else{
                client.disconnect();
                connectBtn.textContent = '连接'
                connect.textContent = '连接断开';
            }
        }

        // 监听发送数据按钮
        sendBtn.onclick = function(){
            if(connectBtn.textContent == '断开'){
                if(issueTopic.value.length > 0 && sendDataArea.value.length > 0){
                    let message;
                    if(checkBox.checked == true){
                        message = new Paho.MQTT.Message(StringToHex(sendDataArea.value));
                    }else{
                        message = new Paho.MQTT.Message(sendDataArea.value);
                    }
                    message.destinationName = issueTopic.value;
                    message.qos = 0;
                    message.retained = false;
                    client.send(message);
                }
            } 
            receiveArea.scrollTop = receiveArea.scrollHeight;
        }
        
        // 监听发送数据的清除
        clearSendData.onclick = function(){
            sendDataArea.value = '';
        }

        // 监听订阅按钮的点击
        subscription.onclick = function(){
            if(connectBtn.textContent == '断开'){
                topic = bottomArea.value;
                if(topic.length == 0){
                    receiveArea.append("\r\n"+'订阅主题不能为空'+"\r\n");
                }else{
                    client.subscribe(topic, { qos: 0, invocationContext: { arg: topic }, onSuccess: SuccessFun, onFailure: FailureFun});
                }
            }else{
                receiveArea.append("\r\n"+'请先连接'+"\r\n");
            }
            receiveArea.scrollTop = receiveArea.scrollHeight;
        }
        
        // 监听数据接收清除按钮的点击
        receiveClear.onclick = function(){
            receiveArea.innerHTML = '';
        }

        // 定义一个订阅成功调用的函数
        function SuccessFun(error){
            receiveArea.append("\r\n"+'订阅成功:'+topic+"\r\n");
            receiveArea.scrollTop = receiveArea.scrollHeight;
        }
        // 定义一个订阅失败的方法
        function FailureFun(error){
            receiveArea.append("\r\n"+'订阅失败'+'topic'+"\r\n");
            receiveArea.scrollTop = receiveArea.scrollHeight;
        }
        
        // 定义一个接收到数据的方法
        function onMessageArrived(message) {//接收到消息
            //console.log("onMessageArrived:"+message.payloadString);
            receiveArea.append("\r\n"+ formartDate(new Date()));
            receiveArea.append("\r\n"+'主题:'+message.destinationName);
            try {//字符串显示
                receiveArea.append("\r\n"+'字符串消息:');
                receiveArea.append(message.payloadString);
                receiveArea.append("\r\n");
            } catch (e) {
                receiveArea.append("\r\n");
            }

            try {//16进制显示
                receiveArea.append('16进制消息:');
                receiveArea.append(hex2str(message.payloadBytes) +"\r\n");
                receiveArea.append("\r\n");
                //console.log(message.payloadBytes);
            } catch (e) {
                receiveArea.append("\r\n");
            }
            receiveArea.scrollTop = receiveArea.scrollHeight;
        }
	
        // 定义一个成功连接的方法
        function onSuccess() {
            connectBtn.textContent = '断开'
            connect.textContent = '连接成功';
            console.log("onConnect");
        }

        // 定义一个连接失败的方法
        function onFailure(error) {
            // Once a connection has been made, make a subscription and send a message.
            // console.log("onFailure");
            receiveArea.append("\r\n"+error.errorMessage+"\r\n");
            connectBtn.textContent = '连接'
            connect.textContent = '连接失败';
            
        }
        
        // 16进制字符串显示形式,转换为16进制数
        function StringToHex(hex) {
            var a = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function (h) {
                return parseInt(h, 16)
            }))
            return a;
        }
        
        // 定义一个时间格式化的方法
        function formartDate(date){
            return `${date.getFullYear()}-${date.getMonth() + 1}-${ date.getDate()} ${date.getHours()}:${date.getMinutes()}:${ date.getSeconds()}`
        }

        // 16进制数,转为字符串显示
        function hex2str(hex) {
			let str = '';
            let i;
          for(i = 0; i < hex.length;i++) {
                if(hex[i] <= 15){
                    str = str + "0"+(hex[i].toString(16)+" ")
                }else{
                    str = str + (hex[i].toString(16)+" ")
                }
          }
           return str;
        }
    </script>
</body>
</html>

三、运行

在服务器上打开宝塔面板,并上传工程目录。

在这里插入图片描述

而后在:http://IP/MqttDebugWeb/打开网页mqtt助手
在这里插入图片描述

如果自己的MQTT服务器的IP地址是 47.92.31.46 WebSocket端口是 8083
则IP地址 ws://47.92.31.46:8083/mqtt

如果自己的MQTT服务器的IP地址是 47.92.31.46 WebSocket+SSL端口是 8084
则IP地址 wss://47.92.31.46:8084/mqtt

提示:ClientID 默认是时间戳加16位随机数,如果自己填写,将使用自己填写的

ReCclay CSDN认证博客专家 视觉/OpenCV 图像处理 深度学习
大家好,我是CSDN博主ReCclay,目前处于研究生阶段,就读于电子科技大学,主攻方向为汽车辅助驾驶算法研究。入站以来,凭借坚持与热爱,以博文的方式分享所学,截止目前累计博文数量达800余篇,受益人次达135万余次,涉及领域包括但不限于物联网开发、单片机开发、Linux驱动开发、FPGA开发、前/后端软件开发等。在未来我将继续专注于嵌入式相关领域,学习更多的科技知识,输出更高质量的博文。希望在”2020博客之星年度总评选“中,可以大家的关注和投票,投票地址:https://bss.csdn.net/m/topic/blog_star2020/detail?username=recclay
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页