美文网首页
mqtt测试工具

mqtt测试工具

作者: nzjcnjzx | 来源:发表于2020-12-25 15:19 被阅读0次

    为了方便测试连接mqtt,自己写了个测试的页面,界面如下图:


    image.png

    代码如下:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="shortcut icon" href="#" />
        <link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.14.1/theme-chalk/index.css" rel="stylesheet" />
        <link rel="stylesheet" href="//at.alicdn.com/t/font_2292707_b2m1g0ybo1.css">
        <style>
            html,
            body {
                margin: 0;
                padding: 0;
                width: 100%;
                height: 100%;
                color: #fff;
                font-size: 16px;
            }
    
            * {
                -webkit-box-sizing: border-box;
                box-sizing: border-box;
            }
    
            #app {
                height: 100%;
                text-align: center;
                overflow: hidden;
            }
    
            .el-container {
                height: 100%;
            }
    
            .el-header,
            .el-footer {
                color: #000;
                line-height: 60px;
                background-color: #d7e2f1;
            }
    
            .el-aside {
                height: 100%;
                color: #333;
                background-color: #D3DCE6;
            }
    
            .history-wrap {
                height: calc(100% - 70px);
                overflow: auto;
            }
    
            .history-link {
                color: #444;
                font-size: 14px;
                line-height: 40px;
                height: 40px;
                cursor: pointer;
            }
    
            i.el-icon-close {
                display: none;
            }
    
            .history-link:hover {
                color: #51a5fa;
            }
    
            .history-link:hover i.el-icon-close {
                display: inline-block;
            }
    
            .active {
                color: #1b89f7;
            }
    
            .el-main {
                height: 100%;
                color: #333;
                background-color: #E9EEF3;
            }
    
            .row {
                margin-bottom: 20px;
            }
    
            .el-button {
                width: 100px;
            }
    
            .el-icon--right {
                margin-right: 10px;
            }
    
            .show-content {
                height: calc(100% - 260px);
                padding: 20px;
                color: #fff;
                background-color: #000;
                text-align: left;
                max-height: 339px;
            }
    
            [v-clock] {
                display: none;
            }
    
            .text {
                text-align: left;
            }
    
            .tip {
                font-size: 12px;
                color: #ccc;
            }
    
            .message-text {
                overflow: auto;
                height: 100%;
                padding: 10px 0;
                word-break: break-all;
                color: #fff;
                background-color: #000;
            }
    
            .iconfont {
                font-size: 14px;
                margin-right: 5px;
            }
        </style>
        <title>mqtt-test</title>
    </head>
    
    <body>
        <div id="app" v-clock>
            <el-container>
                <el-header>MQTT测试工具</el-header>
                <el-container>
                    <el-aside width="200px">
                        <h3>历史记录</h3>
                        <div class="history-wrap">
                            <div @click="onClickHistory(index)" class="history-link" :class="{active: index==currentIndex}"
                                v-for="(item, index) in historyList" :key="index">{{item.ip}} <i
                                    @click.stop="onDelete(index)" class="el-icon-close"></i> </div>
                        </div>
                    </el-aside>
                    <el-main>
                        <div class="row">
    
                            <el-row class="row" :gutter="20" type="flex" align="middle">
                                <el-col :span="6">
                                    <el-row type="flex" align="middle">
                                        <el-col :span="4">IP</el-col>
                                        <el-col :span="20" :push="1">
                                            <el-input v-model="ip" placeholder="请输入ip"></el-input>
                                        </el-col>
                                    </el-row>
                                </el-col>
                                <el-col :span="6">
                                    <el-row type="flex" align="middle">
                                        <el-col :span="4">端口</el-col>
                                        <el-col :span="20" :push="1">
                                            <el-input v-model="port" placeholder="请输入端口"></el-input>
                                        </el-col>
                                    </el-row>
                                </el-col>
                                <el-col :span="6">
                                    <el-row type="flex" align="middle">
                                        <el-col :span="4">路径</el-col>
                                        <el-col :span="20" :push="1">
                                            <el-input v-model="path" placeholder="请输入路径"></el-input>
                                        </el-col>
                                    </el-row>
                                </el-col>
                                <el-col :span="6">
                                    <el-button :disabled="hasConnect" @click="onConnect" type="primary" size="medium"><i
                                            class="iconfont icon-lianjie"></i>连接</el-button>
                                    <el-button :disabled="!hasConnect" @click="onDisconnect" type="primary" size="medium"><i
                                            class="iconfont icon-duankailianjie"></i>断开</el-button>
                                </el-col>
                            </el-row>
                        </div>
                        <div class="row">
                            <el-row :gutter="20" type="flex" align="middle">
                                <el-col :span="6">
                                    <el-row type="flex" align="middle">
                                        <el-col :span="6">订阅主题</el-col>
                                        <el-col :span="18" :push="1">
                                            <el-input v-model="sub" placeholder="请输入订阅主题"></el-input>
                                        </el-col>
                                    </el-row>
                                </el-col>
                                <el-col :span="6">
                                    <el-button :disabled="!hasConnect" @click="onSub" prefix-icon="" type="primary"
                                        size="medium"><i class="iconfont icon-dingyue"></i>订阅</el-button>
                                </el-col>
                            </el-row>
                        </div>
                        <div class="row">
                            <el-row :gutter="20" type="flex" align="middle">
                                <el-col :span="6">
                                    <el-row type="flex" align="middle">
                                        <el-col :span="6">发布主题</el-col>
                                        <el-col :span="18" :push="1">
                                            <el-input v-model="pub" placeholder="请输入发布订阅主题"></el-input>
                                        </el-col>
                                    </el-row>
                                </el-col>
                                <el-col :span="10" :push="1">
                                    <el-row type="flex" align="middle">
                                        <el-col :span="4">发布内容</el-col>
                                        <el-col :span="20" :push="1">
                                            <el-input v-model="content" type="textarea" rows="5" placeholder="请输入发布内容">
                                            </el-input>
                                        </el-col>
                                    </el-row>
                                </el-col>
                                <el-col :span="6" :push="1">
                                    <el-button :disabled="!hasConnect" @click="onPub" type="primary" size="medium"><i
                                            class="iconfont icon-fabu"></i>发布</el-button>
                                    <el-button :disabled="!hasConnect" @click="onClearMessage" type="primary" size="medium">
                                        <i class="iconfont icon-qingchu"></i>清除</el-button>
                                </el-col>
                            </el-row>
                        </div>
                        <div class="show-content">
                            <el-row>
                                <el-col :span="12">
                                    接受的消息:
                                </el-col>
                                <el-col :span="12">
                                    发布的消息
                                </el-col>
                            </el-row>
                            <div class="message-text">
                                <div class="box">
                                    <el-row>
                                        <el-col :span="12">
                                            <div class="sub-box">
                                                <div class="text" v-for="(item,index) in subList" :key="index">
                                                    <span v-html="item"></span>
                                                </div>
                                                <div class="tip" v-if="subList.length == 0">暂未收到消息</div>
                                            </div>
                                        </el-col>
                                        <el-col :span="12">
                                            <div class="text" v-for="(item,index) in pubList" :key="index">
                                                <span v-html="item"></span>
                                            </div>
                                        </el-col>
                                    </el-row>
                                </div>
                            </div>
                        </div>
                    </el-main>
                </el-container>
            </el-container>
        </div>
    </body>
    
    </html>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.14.1/index.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/mqtt/4.2.6/mqtt.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data() {
                return {
                    ip: 'xx.xx.xx.xx',
                    port: '9001',
                    path: '/mqtt',
                    sub: 'test',
                    pub: 'test',
                    content: 'hello',
                    pubList: [],
                    subList: [],
                    client: null,
                    hasConnect: false,
                    historyList: [],
                    currentIndex: -1
                };
            },
            computed: {
                num() {
                    return this.subList.length > 0 ? '12' : '0'
                }
            },
            watch: {
                subList(n, o) {
                    this.$nextTick(() => {
                        const ele = document.querySelector('.message-text')
                        ele.scrollTop = ele.scrollHeight;
                    });
                },
                historyList(n) {
                    console.log(n)
                }
            },
            methods: {
                initStatus() {
                    this.hasConnect = false;
                    this.client && this.client.end()
                    this.client = null;
                },
                onDelete(index) {
                    this.historyList.splice(index, 1)
                    this.setHistoryList(index - 1)
                },
                onClickHistory(index) {
                    this.currentIndex = index
                    if (this.historyList.length == 0) return;
                    const {
                        ip,
                        port,
                        path,
                        sub,
                        pub,
                        content
                    } = this.historyList[index]
                    this.ip = ip
                    this.port = port
                    this.path = path
                    this.sub = sub
                    this.pub = pub
                    this.content = content
                    this.initStatus()
                },
                successTip(message) {
                    this.$message({
                        type: 'success',
                        message
                    })
                },
                now() {
                    return moment().format('YYYY-MM-DD HH:mm:ss')
                },
                formatMessage(topic, message) {
                    return `<span style="color: #00A000;">| ${this.now()} | 主题名称: ${topic} |</span>
                     <br>
                     <span style="word-break: break-all;line-height:1.2;padding:5px;">${message}</span>
                    `
                },
                onSub() {
                    this.successTip(`订阅了主题${this.sub}`)
                    this.client && this.client.subscribe(this.sub)
                    this.updateHistoryList()
                },
                onPub() {
                    this.pubList.push(this.formatMessage(this.pub, this.content))
                    this.client && this.client.publish(this.pub, this.content);
                    this.updateHistoryList()
                },
                onDisconnect() {
                    this.initStatus()
                },
                onConnect() {
                    this.client = mqtt.connect(`ws://${this.ip}:${this.port}${this.path}`);
                    this.client.on('connect', this.onConnectMqtt)
                    this.client.on('error', this.onError)
                    this.client.on('message', this.onMessage)
                    this.client.on('close', this.onClose)
                    this.historyList.unshift({
                        ip: this.ip,
                        port: this.port,
                        path: this.path
                    })
                    this.setHistoryList()
                },
                updateHistoryList() {
                    this.historyList[this.currentIndex] = {
                        ...this.historyList[this.currentIndex],
                        pub: this.pub,
                        sub: this.sub,
                        content: this.content
                    }
                    this.setHistoryList(this.currentIndex)
                },
                setHistoryList(index = 0) {
                    if (index < 0) index = 0;
                    localStorage.setItem('history', JSON.stringify(this.historyList))
                    this.currentIndex = index
                },
                onConnectMqtt(e) {
                    console.log(e)
                    this.hasConnect = true
                    this.successTip('连接成功')
                },
                onMessage(topic, payload) {
                    console.log(topic, payload.toString())
                    this.subList.push(this.formatMessage(topic, payload.toString()))
                },
                onClearMessage() {
                    this.subList = []
                    this.pubList = []
                },
                onClose() {
                    if (!this.hasConnect) return this.$message({
                        type: 'info',
                        message: '已断开连接'
                    })
                    this.hasConnect = false;
                    this.$message.error('连接不成功,连接关闭!')
                    this.client.end()
                },
                onError(err) {
                    console.error(err)
                    this.$message.error(`出现错误了错误信息是${JSON.stringify(err)}`)
                    this.client.end()
                },
                init() {
                    this.historyList = localStorage.getItem('history') ? JSON.parse(localStorage.getItem(
                        'history')) : []
                    this.onClickHistory(0)
                }
            },
            mounted() {
                this.init()
            },
        });
        Vue.config.errorHandler = function (err, vm, info) {
            console.log(`Error: ${err.toString()}\nInfo: ${info}`);
            app.$message.error(err.message)
        }
    </script>
    

    插件全部为外链接,可以直接新建html文件拷入,双击打开使用

    相关文章

      网友评论

          本文标题:mqtt测试工具

          本文链接:https://www.haomeiwen.com/subject/sdxinktx.html