使用uni-app开发app时遇到mqtt.js不可用的问题

news/2024/9/19 1:33:08/ 标签: uni-app, javascript, 安卓, 前端框架

使用uni-app开发app时遇到mqtt.js不可用的问题

1 问题背景

基于 Vue3 版本创建了 uni-app 项目用于开发微信小程序,项目中用到了 mqtt.js(v4.1.0),编译为微信小程序能够正常运行,但是编译为 APP 后,控制台打印出如下错误:

TypeError: socketTask.onOpen is not a function

看到 socketTask 后立刻想到了微信小程序,个人以为是 mqtt 连接地址的问题。因为在微信小程序中使用 mqtt.js 时需要将 mqtt 连接地址写为 wx:IP地址:端口号/mqtt,所以把连接地址改为了 ws:IP地址:端口号/mqtt,重新运行后控制台打印出如下错误:

TypeError: WS is not a constructor

经过查看源码(node_modules/mqtt/dist/mqtt.js)发现相关代码如下:

// ... other code ...
var WS = require('ws')// ... other code ... if (isNative && isBrowser) {socket = new WS(target, protocols)
} else {socket = new WS(target, protocols, options)
}

添加 console.log() 语句查看 WS 变量后发现控制台打印结果为 null,即引入第三方库 ws 失败。

直接在 pages/index/index.vue 中引入 ws 库并打印变量,打印结果如下:

// pages/index/index.vue
const WS = require('ws')
console.log(WS)
# 控制台打印结果
function() {throw new Error('ws does not work in the browser. Browser clients must use the native ' + 'WebSocket object');
}

2 引发原因

经查看 ws 库的 Github 主页 发现该库仅在 Node.js 环境下运行。结合提示信息,说明 uni-app 在 APP 端的运行环境和浏览器相关。

随后查询官方文档发现:

vue页面在App端,默认是被系统的webview渲染的(不是手机自带浏览器,是rom的webview)。

也就是说 uni-app 在 APP 端的运行环境是 webview,而 ws 库仅在 Node.js 环境下运行,从而导致通过 require() 引入后为 null。

3 解决方法

既然 uni-app 在 APP 端的运行环境是 webview,而微信小程序的运行环境也是 webview,二者运行环境相似,应该可以共用一个创建 WebSocket 连接的 API。而 mqtt.js 在小程序环境中可以正常运行,所以首先将 mqtt 连接地址改回 wx:IP地址:端口号/mqtt,通过小程序 API wx.connectSocket() 创建 WebSocket 连接。

但是问题又回到了一开始,运行后控制台会打印如下错误信息:

TypeError: socketTask.onOpen is not a function

3.1 解决方法1:降低 Vue 版本【推荐⭐】

搜索了很多教程,发现其发布时间多为 2019 ~ 2021,然后想到会不会是 Vue 版本较高导致,尝试降低为 Vue2 版本后重新运行,发现运行成功。

3.2 解决方法2:修改 mqtt.js 源码【推荐⭐⭐⭐⭐⭐】

搜索教程中发现修改源码(node_modules/mqtt/dist/mqtt.js)中的 wx.connectSocket() 也可以解决,解决方法是在调用 wx.connectSocket() 时传入回调函数。

socketTask = wx.connectSocket({url: url,protocols: [websocketSubProtocol],success() {} // 增加这行代码
})

具体原理可见 uni-app 官方API uni.connectSocket():

对于 uni.connectSocket() API 而言:

如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象;

如果希望返回一个 socketTask 对象,需要至少传入 success / fail / complete 参数中的一个。

所以上面新增的回调函数也可以改为 fail() {}complete() {}


http://www.ppmy.cn/news/1433523.html

相关文章

C# winform OpenProtocol中数据中的UI是什么类型?

C# winform OpenProtocol中数据中的UI是什么类型?

Nginx安装withSSL模块

Nginx安装withSSL模块 Nginx 配置文件,开启ssl访问时,报出错误信息: nginx: [emerg] the “ssl” parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx_proxy.mimvp.com.conf:76 原因分析: nginx缺少http_ssl_module…

Unity系统学习笔记

文章目录 1.基础组件的认识1.0.组件继承关系图1.1.项目工程文件结构,各个文件夹都是做什么的?1.2.物体变化组件1.2.3.三维向量表示方向1.2.4.移动物体位置附录:使用变换组件实现物体WASD移动 1.3.游戏物体和组件的显示和禁用1.3.1.界面上的操…

数据结构 - 顺序表实现通讯录

test.c文件 #define _CRT_SECURE_NO_WARNINGS 1#include "Contact.h" int main() {Con myContacts;ConInit(&myContacts);int choice;int index;char targetName[100];PerInfo contact; // 创建一个新的联系人信息实例while (1) {printf("\n--- 通讯录管理…

PaddleSeg (2) 模型训练

已处理好数据集和配置文件,可以开始模型训练。 启动训练 python tools/train.py --config configs/xxx.yml --do_eval --use_vdl --save_interval 500 --save_dir output/xxx上述训练命令解释:* `--config`

java spring 07 createBean()和doCreateBean()

01.createBean方法 protected Object createBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean " beanName "");}RootBea…

引导过程和服务控制

1、Linux系统开机引导过程 1)开机自检 检测硬件设备,找到能够引导系统的设备,比如硬盘 2)MBR引导 运行MBR扇区里的主引导程序GRUB 3)启动GRUB菜单 系统读取GRUB配置文件(/boot/grub2/grub.cfg)获取内…

spring boot 定义启动页 到 login

当前办法只是针对 项目启动后 直接跳转到 指定静态页面 如果有验证身份 安全等问题 可以另外想办法 去添加 ,需要的直接 拉过去使用 修改 【"redirect: 需要启动后访问到文件位置得地址 ”】 直接上代码 : import org.springframework.context…

【教程】使用vitepress搭配githubPages构建自己的在线笔记

1. 创建VitePress项目 确保自己已经安装好了node,我这个笔记用的是node 18.16.0, 怎么安装nvm这个可以csdn或者掘金,再或者等我有空了我就更新一下 使用nvm安装node # 查看可用版本 nvm list avaliable # 安装node nvm install 18.16.0 # 切换node nvm …

(C语言)sscanf 与 sprintf详解

目录 1.sprintf函数详解 2. sscanf函数详解 1.sprintf函数详解 头文件&#xff1a;stdio.h 作用&#xff1a;将格式化的数据写入字符串里&#xff0c;也就是将格式化的数据转变为字符串。 演示&#xff1a; #include <stdio.h> struct S {char name[10];int height;…

无人机探测技术,无人机侦测频谱仪技术实现详解

频谱仪&#xff0c;又称为频谱分析仪&#xff0c;是一种用于测量电信号频谱特性的仪器。其基本原理是通过将时域信号转换为频域信号&#xff0c;进而分析信号的频率成分、功率分布、谐波失真等参数。频谱仪利用快速傅里叶变换&#xff08;FFT&#xff09;算法&#xff0c;将采集…

Github 2024-04-24 C开源项目日报 Top9

根据Github Trendings的统计,今日(2024-04-24统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目9C++项目1我的电视 - 安卓电视直播软件 创建周期:40 天开发语言:CStar数量:649 个Fork数量:124 次关注人数:649 人贡献人数:1 人Open…

STM32 USB HID报告描述符没有报告长度

STM32 USB HID设置(STM32CubeMX)_我也想成大侠的博客-CSDN博客 不影响鼠标功能

面向对象设计模式

设计模式通常被分为三种类型&#xff1a;创建型模式、结构型模式和行为型模式。 创建型模式 创建型模式主要关注对象的创建机制&#xff0c;它们提供了一种将对象创建和实例化的机制&#xff0c;使得系统在不直接依赖于具体类的情况下能够灵活地创建对象。 创建型模式的典型…

力扣---填充每个节点的下一个右侧节点指针 II

给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL 。 初始状态下&#xff0c;所有 next 指针都…

Prompt Engineering,提示工程

什么是提示工程&#xff1f; 提示工程也叫【指令工程】。 Prompt发送给大模型的指令。比如[讲个笑话]、[用Python编个贪吃蛇游戏]、[给男/女朋友写情书]等看起来简单&#xff0c;但上手简单精通难 [Propmpt]是AGI时代的[编程语言][Propmpt]是AGI时代的[软件工程][提示工程]是…

Spring5深入浅出篇:JDK代理与CGLIB代理区别

Spring5深入浅出篇:JDK代理与CGLIB代理区别 很多粉丝私信我这个Spring5的课程在哪看,这边是在B站免费观看欢迎大家投币支持一下. https://www.bilibili.com/video/BV1hK411Y7zf JDK动态代理与CGLIB的区别 在Java的世界里&#xff0c;动态代理主要有两种实现方式&#xff1a;JDK…

广州大学《虚拟现实与游戏开发》实验报告一HTC-VR环境搭建与开发

广州大学学生实验报告 开课实验室&#xff1a; 学院 年级、专业、班 姓名 学号 实验课程名称 虚拟现实与游戏开发 成绩 实验项目名称 1. HTC-VR环境搭建与开发 指导老师 实验目的 HTC VIVE硬件安装虚拟现实开发环境搭建 3.熟悉虚拟现实硬件系统和…

springboot-异步、定时、邮件任务

目录 一&#xff0c;前言 二&#xff0c;异步 2.1&#xff0c;案例&#xff1a; 1&#xff0c;首先创建一个service&#xff1a; 2&#xff0c;Controller: ① 想办法告诉spring我们的异步方法是异步的&#xff0c;所以要在方法上添加注解 Async ②去springboot主程序中开…

深入Spring Boot配置机制:如何高效管理应用配置

一、属性的优先级和配置文件的位置 在Spring Boot应用中&#xff0c;我们可以在多个地方定义配置属性&#xff0c;并且Spring Boot提供了一套优先级排序&#xff0c;来决定同一属性多处定义时的覆盖关系。理解这个机制对于配置管理至关重要。 1. 配置文件查找的顺序 Spring …