在vue使用MQTT
在vue中使用MQTT
最近有个需求,需要前端直接链接mqtt,想到后面可能多出使用,就封装成了hooks
中间遇到了一个坑,就是浏览器默认不支持mqtt协议,其借助了webSocket实现的mqtt协议,
而mqtt默认未开启webSocket官网中并说明,但其demo中都是使用的ws,最后通过不断的摸索确认是
需要在配置中进行相关配置
安装mqtt插件
pnpm add mqtt
or
npm i mqtt
or
yarn add mqtt
导入mqtt
import * as mqtt from "mqtt/dist/mqtt.min"
封装
这个封装只需要稍加改动就能在react中使用
import * as mqtt from "mqtt/dist/mqtt.min";
import {onUnmounted, reactive, ref} from "vue";export default function useMqtt(options, getMessage) {const data = ref();const connection = reactive({protocol: options.host ?? 'ws',host: options.host ?? '81.69.203.93',port: options.port ?? 8083,clientId: options.clientId ?? "mqttx_" + Math.random().toString(16).substring(2, 8),username: options.username ?? 'bduser',password: options.password ?? '123456',clean: options.clean ?? true,connectTimeout: options.connectTimeout ?? 30 * 1000, // msreconnectPeriod: options.reconnectPeriod ?? 4000 // ms});/*** 订阅信息设置*/const subscription = ref({topic: options.subscription.topic, //需要动态配置qos: options.subscription.qos});let client = ref({connected: false});const receivedMessages = ref("");const subscribedSuccess = ref(false);const btnLoadingType = ref("");const retryTimes = ref(0);/*** 初始化*/const initData = () => {client.value = {connected: false};retryTimes.value = 0;btnLoadingType.value = "";subscribedSuccess.value = false;};const handleOnReConnect = () => {console.log(`第${retryTimes.value}次重试`);retryTimes.value += 1;if (retryTimes.value > 5) {try {client.value.end();initData();} catch (error) {console.error(error)}}};/*** 创建连接*/const createConnection = () => {try {btnLoadingType.value = "connect";console.log('connection----->', connection)const {protocol, host, port, ...options} = connection;const connectUrl = `${protocol}://${host}:${port}/mqtt`;client.value = mqtt.connect(connectUrl, options);if (client.value.on) {client.value.on("connect", () => {btnLoadingType.value = "";console.log("------链接建立成功------");});client.value.on("reconnect", handleOnReConnect);client.value.on("error", (error) => {console.error("------链接建立失败------", error)});client.value.on("message", (topic, message) => {receivedMessages.value = receivedMessages.value.concat(message.toString());data.value = JSON.parse(message);if (getMessage) getMessage(message);console.log("收到的数据--------------", data.value);});}} catch (error) {btnLoadingType.value = "";console.error("链接出错", error);}};/*** 订阅消息*/const doSubscribe = () => {btnLoadingType.value = "subscribe";const {topic, qos} = subscription.value;console.log("订阅消息------->", `$queue${topic}`, qos);client.value.subscribe(`$queue${topic}`, {qos}, (error, granted) => {btnLoadingType.value = "";if (error) {console.log("subscribe error:", error);return;}subscribedSuccess.value = true;console.log("subscribe successfully:", granted);});};/*** 关闭连接*/const destroyConnection = () => {if (client.value.connected) {btnLoadingType.value = "disconnect";try {client.value.end(false, () => {initData();console.log("disconnected successfully");});} catch (error) {btnLoadingType.value = "";console.log("disconnect error:", error);}}};/*** 发送消息* @param data*/const publishMessage = (data) => {btnLoadingType.value = "publish";const {topic, qos} = subscription.valueconsole.log(`发送消息到【${topic}】-【${qos}】`)client.value.publish(`${topic}`, data, {qos}, (error) => {btnLoadingType.value = "";if (error) {console.error("消息发送失败", error);return;}console.log(`消息内容${data}`);});};/*** 取消订阅*/const doUnSubscribe = () => {btnLoadingType.value = "unsubscribe";const {topic, qos} = subscription.value;console.warn("取消订阅------->", `$queue${topic}`, qos);client.value.unsubscribe(`$queue${topic}`, {qos}, (error) => {btnLoadingType.value = "";subscribedSuccess.value = false;if (error) {console.log("unsubscribe error:", error);return;}console.log(`unsubscribed topic: ${topic}`);});};/*** 创建连接并订阅*/const createAndDo = () => {createConnection();doSubscribe();}// //组件销毁前断开连接onUnmounted(() => {console.log("------页面销毁前断开连接------");destroyConnection();});return {data,publishMessage,connection,subscription,doUnSubscribe,destroyConnection,createConnection,doSubscribe,createAndDo};
}
相关文章:
在vue使用MQTT
在vue中使用MQTT 最近有个需求,需要前端直接链接mqtt,想到后面可能多出使用,就封装成了hooks 中间遇到了一个坑,就是浏览器默认不支持mqtt协议,其借助了webSocket实现的mqtt协议, 而mqtt默认未开启webSocke…...
DNS、网关、IP、DHCP
DNS、网关、IP、DHCP:深入剖析与理解 在计算机网络的世界中,DNS、网关、IP和DHCP是四个至关重要的概念,它们共同构建了互联网的基础架构,确保了数据的准确传输和设备的有效连接。本文将深入剖析这四个概念,帮助读者更…...
vue2 vue3 props 的处理机制
在 Vue 2 中,props 是单向数据流,父组件向子组件传递的 props 默认情况下是不具有响应式特性的。这意味着当父组件的数据发生变化时,如果传递给子组件的 props 发生变化,子组件不会自动更新视图。 具体来说,在 Vue 2 …...
C++第十弹 ---- vector的介绍及使用
目录 前言vector的介绍及使用1. vector的使用1.1 vector的定义1.2 iterator的使用1.3 vector空间增长问题1.4 vector增删查改 2. vector迭代器失效问题(重点) 总结 前言 本文介绍了C中的vector数据结构及其使用方法。 更多好文, 持续关注 ~ 酷酷学!!! 正文开始 vector的介绍…...
ValueError: invalid literal for int() with base 10: ‘a‘
ValueError: invalid literal for int() with base 10: ‘a‘ 目录 ValueError: invalid literal for int() with base 10: ‘a‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰ÿ…...
[C++探索]初始化列表,static成员,友元函数,内部类,匿名对象
💖💖💖欢迎来到我的博客,我是anmory💖💖💖 又和大家见面了 欢迎来到C探索系列 作为一个程序员你不能不掌握的知识 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低成本搭建个人网站…...
搭建自己的金融数据源和量化分析平台(二):读取上交所股票列表
我在上交所没发现上交所有像深交所一样的一键下载股票xls文档的按钮,因此上交所的股票列表读取就会比较麻烦。总体思路是查出来所有股票的代码之后根据股票代码逐一发起HTTP请求读取公司英文名、总股本、流通股本等详细信息,这就导致上交所爬虫的网络交互…...
Kafka知识总结(分区机制+压缩机制+拦截器+副本机制)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 分区机制 分区策略 分区策略是决定生产者将消息发送到哪个分区的…...
WordPress原创插件:搜索引擎抓取首图seo图片
WordPress原创插件:搜索引擎抓取首图seo图片 插件设置 插件将在网站头部添加适当的meta标签,以便百度等搜索引擎抓取指定的固定图像。 插件下载 https://download.csdn.net/download/huayula/89596527...
Android Framework 之AMS
它管理了系统的四大组件:Activity、Service、ContentProvider、Broadcast。 它除了管理四大组件外,同时也负责管理和调度所有的进程 AMS相关目录结构 AMS代码主要在下面几个目录(AndroidQ上AMS相关部分功能移到了wm下): frameworks/base/core/java/andro…...
AnConda环境配置学习笔记
AnConda环境配置 个人笔记,自己学习使用。 1、软件安装 去官网或者是清华大学镜像下载 2、环境配置 Conda 查看版本:conda --version 更新所有库 conda update --all(千万不要跟新,版本不匹配) matploitlib安装cond…...
架构师的36项修炼 学习笔记
架构师的36项修炼 学习笔记 分布式缓存 缓存特点 1.技术简单 2.性能提升明显 3.应用场景多 缓存数据存储 hash表 缓存的关键指标 命中率 缓存失效方式 超时失效 LLT 实时清除 代理缓存 反向代理缓存 多层反向代理缓存 内容分发网络CDN 通读缓存 包括代理缓存…...
Python | “IndexError: tuple index out of range” 【已解决】
Python | “IndexError: tuple index out of range” 【已解决】 IndexError: tuple index out of range 深度解析与实战指南 在Python编程中,IndexError: tuple index out of range是一个常见的错误,它发生在尝试访问元组(或其他可索引的数…...
Linux上部署easySpider及基本使用
一、安装及简介 默认使用Chrome浏览器。 1、下载压缩包 官网:易采集EasySpider:无代码可视化爬虫/浏览器自动化测试软件 Linux版只适用于Ubuntu 20.04及以上版本、Deepin、Debian及其衍生版本。 (建议使用)下载网址/Github下…...
Qt Designer,仿作一个ui界面的练习(二):部件内容的填充
有了完成了布局的基本框架设计之后,对各个部件逐步完成内容的填充。 一、还是从顶边栏开始: 1、在顶边栏的topLogo里面拖入一个QLabel(标签),命名为logoImage,删除标签的文字。 2、右键点击topLogo&#x…...
LIS2DH12传感器底电流100ua处理
默认已经正常初始化IIC和LIS2DH12之后,需要正常开启和进入低功耗传感器的处理。 主要是对两个寄存器的处理:20、1E ODR[3:0]数据速率选择。默认值:0000(0000:断电模式;其他:见表31&a…...
五、Spring Boot - 上手篇(1)
🌻🌻目录 一、快速入门:创建第一个SpringBoot 工程1.1 点击File--->New--->Project...1.2 选择版本和依赖的相关骨架包1.3 设置项目保存目录1.4 项目创建完成,工程主界面如下1.5 项目说明1.6 启动项目1.7 编写 HelloControl…...
Spring -- 使用XML开发MyBatis
T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 今天你敲代码了吗 文章目录 MyBatis XML配置文件开发配置连接字符串和MyBatis写Mapper层代码添加mapper接口添加UserInfoXmLMapper.xml 操作数据库INSERTDELETE & UPDATE MyBatis XML配置文件开发 实际上,除…...
openmv 学习笔记(24电赛笔记)
寻找特定目标 这个功能主要应用在,机器人寻找色块,无人机跟踪特定颜色,生产线上检测物体进行分类,还有人机交互等等功能应用。 相关函数 image.find_blobs(thresholds, roiAuto, x_stride2, y_stride1, invertFalse, area_thr…...
【C语言】【数据结构】二分查找(数组的练习)
目录 一、什么是二分查找 二、算法思想 2.1、概述 2.2、举例 (1)查找3(数组里面存在的数) (2)查找12(数组里面不存在的数) 三、代码实现 四、计算mid公式的优化 一、…...
【Python内存管理终极指南】:20年专家亲授智能体内存优化的5大架构设计图与3个致命误区
第一章:Python智能体内存管理的核心原理与演进脉络 Python的内存管理并非由开发者手动控制,而是由解释器内置的“智能体”协同完成——它融合了引用计数、循环垃圾回收(GC)和内存池机制三重策略,在运行时动态权衡效率与…...
uniapp日期处理全攻略:获取某月首尾日、近七天日期等实用技巧
Uniapp日期处理实战:从基础格式化到高级业务场景解决方案 在移动应用开发中,日期处理几乎贯穿所有业务场景。无论是电商平台的限时抢购、医疗应用的预约挂号,还是企业系统的报表统计,精准高效的日期操作都是保障业务逻辑完整性的关…...
MedGemma X-Ray 场景应用:基层医生的AI辅助阅片实战指南
MedGemma X-Ray 场景应用:基层医生的AI辅助阅片实战指南 1. 基层医疗的痛点与AI解决方案 在基层医疗机构,放射科医生常常面临两大挑战:一是阅片经验相对不足,二是工作负荷过重。一张胸部X光片可能包含数十个需要观察的关键点&am…...
终极指南:如何用Hammer.js为AR应用打造自然手势交互体验
终极指南:如何用Hammer.js为AR应用打造自然手势交互体验 【免费下载链接】hammer.js A javascript library for multi-touch gestures :// You can touch this 项目地址: https://gitcode.com/gh_mirrors/ha/hammer.js Hammer.js是一个强大的JavaScript库&am…...
自媒体人的秘密武器:OpenClaw+nanobot自动生成视频字幕文件
自媒体人的秘密武器:OpenClawnanobot自动生成视频字幕文件 1. 为什么我们需要自动化字幕生成 作为一个长期在视频创作领域摸索的自媒体人,我深知字幕制作这个环节有多折磨人。曾经为了给一段10分钟的视频添加字幕,我需要反复暂停播放、手动…...
各行业开发经验全面解析,本凡科技助你快速提升项目成功率
在当今快速发展的市场中,各行业的开发经验已成为决定项目成败的关键因素。每个行业都面临独特的挑战和需求,了解这些特性有助于企业制定有效的开发策略。例如,科技行业通常需要快速响应市场变化,而食品行业则需关注合规性和安全标…...
S3 文件操作进阶实践:从基础上传到完整性保障
1. S3文件操作的核心挑战与解决方案 第一次接触AWS S3时,很多人会觉得文件上传下载不就是调用几个API的事?但真正投入生产环境后,各种问题就会接踵而至。我见过最典型的案例是某电商平台在促销期间,因为文件上传没有做完整性校验…...
Ollama平台部署GLM-4.7-Flash:从零开始搭建本地大模型服务
Ollama平台部署GLM-4.7-Flash:从零开始搭建本地大模型服务 1. 为什么选择GLM-4.7-Flash? 在众多开源大模型中,GLM-4.7-Flash以其独特的定位脱颖而出。这个30B参数的MoE(混合专家)模型,在性能与效率之间取…...
OpenClaw技能扩展指南:为百川2-13B添加公众号发布模块
OpenClaw技能扩展指南:为百川2-13B添加公众号发布模块 1. 为什么需要公众号发布技能 上周我正忙着准备一篇技术分享文章,突然意识到一个痛点:每次写完Markdown文档后,手动复制到公众号编辑器、调整格式、上传封面、设置摘要的过…...
XML Notepad:免费高效的XML编辑器终极指南
XML Notepad:免费高效的XML编辑器终极指南 【免费下载链接】XmlNotepad XML Notepad provides a simple intuitive User Interface for browsing and editing XML documents. 项目地址: https://gitcode.com/gh_mirrors/xm/XmlNotepad XML Notepad是一款由微…...
