MQTT-Vue整合

Vue整合

依赖环境

  • nodejs 版本 >= 18
  • 安装 element plus
npm install element-plus
  • 安装 mqtt
npm install mqtt

初始化Vue项目

  • 使用 vite 创建项目
  1. 执行命令 npm create vite@latest
  2. 输入项目名称 vue-mqtt-demo

在这里插入图片描述

MQTT连接

连接组件代码

components/MqttDemo.vue

<script setup>
import { ref } from "vue";
import mqtt from "mqtt";

// 消息质量取值数组
const qosList = [0, 1, 2];


/* -------建立和关闭连接-------*/
// 定义链接信息对象
const connectionInfo = ref({
  protocol: 'ws',
  host: "192.168.40.128",
  port: 8083,
  clientId: "mqtt_vue_" + Math.random().toString(16).substring(2, 8),
  username: "admin",
  password: "admin123456",
  clean: true,
  connectTimeout: 10 * 1000, // 单位:ms
  reconnectPeriod: 4000, // 单位:ms
})

// 创建链接对象
const client = ref({})
// 链接初始化相关数据
const clientInitData = ref({      
  connnected: false
})

// 建立连接事件处理函数
const createConnection = () => {

  const { protocol, host, port , ...options } = connectionInfo.value;
  const connectUrl = `${protocol}://${host}:${port}/mqtt`;
  console.log(connectUrl)
  // 建立连接
  client.value = mqtt.connect(connectUrl , options);   
  clientInitData.value.connnected = true ;
  console.info("create connection successful...")

}

// 关闭连接
const closeConnection = () => {

  // 如果设置为true:立即关闭套接字,不发送MQTT DISCONNECT包。
  // 如果设置为false(默认值):先发送MQTT DISCONNECT包给代理,然后关闭套接字
  client.value.end(false , () => {
    clientInitData.value.connnected = false;
    console.info("close connection successful...")
  })
}
</script>

<template>
  <div class="mqtt-demo">
    <el-card>
      <h1>配置信息</h1>
      <el-form label-position="top">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item prop="protocol" label="选择协议">
              <el-select v-model="connectionInfo.protocol">
                <el-option label="ws://" value="ws"></el-option>
                <el-option label="wss://" value="wss"></el-option>
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item prop="host" label="主机地址">
              <el-input v-model="connectionInfo.host"></el-input>
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item prop="port" label="端口号">
              <el-input type="number" placeholder="8083/8084" v-model="connectionInfo.port"></el-input>
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item prop="clientId" label="客户端ID">
              <el-input v-model="connectionInfo.clientId"> </el-input>
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item prop="username" label="用户名">
              <el-input v-model="connectionInfo.username"></el-input>
            </el-form-item>
          </el-col>

          <el-col :span="8">
            <el-form-item prop="password" label="密码">
              <el-input v-model="connectionInfo.password"></el-input>
            </el-form-item>
          </el-col>

          <el-col :span="24">
            <el-button type="primary" @click="createConnection" v-bind:disabled="clientInitData.connnected">建立连接</el-button>
            <el-button type="danger" @click="closeConnection" v-bind:disabled="!clientInitData.connnected">断开连接</el-button>
          </el-col>
        </el-row>
      </el-form>
    </el-card>
  </div>
</template>

<style>
.mqtt-demo {
  max-width: 1200px;
  margin: 32px auto 0 auto;
}

h1 {
  font-size: 16px;
  margin-top: 0;
}

.el-card {
  margin-bottom: 32px;
}
.el-card__body {
  padding: 24px;
}

.el-select {
  width: 100%;
}

.text-right {
  text-align: right;
}

.sub-btn {
  margin-top: 30px;
}
</style>

首页引入连接组件

App.vue

<template>
  <MqttDemo />
</template>

<script setup>
import MqttDemo from "./components/MqttDemo.vue";

</script>

<style></style>

运行项目

npm run dev

在这里插入图片描述

访问页面

http://localhost:5173/

在这里插入图片描述

建立连接

在这里插入图片描述

断开连接

在这里插入图片描述

MQTT订阅

订阅相关代码

components/MqttDemo.vue

  • JS 代码
// 消息质量取值数组
const qosList = [0, 1, 2];

/* -----订阅和取消订阅------ */

const receivedMessages = ref(null);
const subscriptionInfo = ref({
  // 订阅参数数据模型
  topic: "",
  qos: 0,
});
const subscriptionInitData = ref({
  // 订阅初始化数据
  subscription: false,
});

// 订阅主题的事件处理函数
const subscriptionTopicHandler = () => {
  const { topic, qos } = subscriptionInfo.value;
  console.info(qos);
  client.value.subscribe(topic, { qos }, (error, res) => {
    if (error) {
      console.info("subscribe topic error:", error);
      return;
    }
    subscriptionInitData.value.subscription = true;
    console.info("subscribe topic successful.... ");

    // 订阅成功以后,监听发送消息事件
    client.value.on("message", (topic, message) => {
      console.info("topic -----> " + topic + ", message -----> " + message);
      receivedMessages.value =
        "topic -----> " + topic + ", message -----> " + message;
    });
  });
};

// 取消订阅的事件处理函数
const unSubscriptionTopicHandler = () => {
  const { topic, qos } = subscriptionInfo.value;
  client.value.unsubscribe(topic, { qos }, (error, res) => {
    if (error) {
      console.info("unSubscriptionTopic Error:", error);
      return;
    }
    subscriptionInitData.value.subscription = false;
    console.info("unSubscriptionTopic successful.... ");
  });
};

  • HTML 页面
 <el-card>
      <h1>订阅主题</h1>
      <el-form label-position="top">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item prop="topic" label="Topic">
              <el-input v-model="subscriptionInfo.topic"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="qos" label="QoS">
              <el-select v-model="subscriptionInfo.qos">
                <el-option
                  v-for="qos in qosList"
                  :key="qos"
                  :label="qos"
                  :value="qos"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-button type="primary" class="sub-btn" @click="subscriptionTopicHandler"
            v-bind:disabled="subscriptionInitData.subscription">订阅主题</el-button>
            <el-button type="primary" class="sub-btn" @click="unSubscriptionTopicHandler"
            v-bind:disabled="!subscriptionInitData.subscription">取消订阅</el-button>
          </el-col>
        </el-row>
      </el-form>
    </el-card>
    <el-card>
      <h1>接收到的消息</h1>
      <el-col :span="24">
        <el-input type="textarea" :rows="3" readonly v-model="receivedMessages"></el-input>
      </el-col>
    </el-card>

运行访问

在这里插入图片描述

订阅主题

在这里插入图片描述

取消订阅

在这里插入图片描述

MQTT 发布

发布相关代码

  • JS 代码
/* ----- 发布消息 ----- */
// 定义发布消息对象
const publishInfo = ref({
  topic: '' ,
  qos: 0,
  payLoad: ''
})
    
// 发布消息的事件处理函数
const publishMsg = () => {
  const {topic , payLoad , qos } = publishInfo.value ;
  client.value.publish(topic , payLoad , { qos } , (error , res) => {
    if(error) {
      console.info("publish msg info error...." , error)
      return ;
    }
    console.info("publish msg info successful....")
  }) ;

}
  • HTML 代码
 <el-card>
      <h1>发布消息</h1>
      <el-form label-position="top">
        <el-row :gutter="20">
          <el-col :span="8">
            <el-form-item prop="topic" label="Topic">
              <el-input v-model="publishInfo.topic"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="payload" label="Payload">
              <el-input v-model="publishInfo.payLoad"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="qos" label="QoS">
              <el-select v-model="publishInfo.qos">
                <el-option
                  v-for="qos in qosList"
                  :key="qos"
                  :label="qos"
                  :value="qos"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-col :span="24" class="text-right">
        <el-button type="primary" @click="publishMsg">发布消息</el-button>
      </el-col>
    </el-card>

运行访问

在这里插入图片描述

订阅主题 test

在这里插入图片描述

发送接收消息

在这里插入图片描述
点击发送后,接收消息框立马收到发布的消息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜逼の世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值