mqttjs / MQTT.js

The MQTT client for Node.js and the browser
Other
8.53k stars 1.41k forks source link

[Bug]:TypeError when packaging Android package with uniapp: WebSocket is not a constructor #1919

Closed AppSkyBoy closed 1 month ago

AppSkyBoy commented 1 month ago

MQTTjs Version

4.0.0

Broker

RabbitMQ

Environment

Browser

Description

MQTT runs well in browsers, but when packaging Android with Uniapp, a TypeError appears: WebSocket is not a constructor. 5.0.0 and above, it was found that there are still many web interfaces that cannot be found when packaging Android

Minimal Reproduction

After Uniapp is packaged in Android, a TypeError will appear upon connection: WebSocket is not a constructor

Debug logs

16:30:22.668 TIM 16:30:21 GMT+0800 (CST).920 TIM.VERSION:2.23.1 16:30:22.707 APP-PLUS at components/mqtt/mqtt.js:21 16:30:22.717 [Vue warn]: Error in onLaunch hook: "TypeError: WebSocket is not a constructor"

(found at App.vue:1) 16:30:22.726 TypeError: WebSocket is not a constructor

robertsLando commented 1 month ago

Please use mqtt latest and show me the error with that.

AppSkyBoy commented 1 month ago

Mqtt 5.9.1 reported JSException>>>>exception function: creatInstanceContext, exception: white screen cause create instanceContext failed, check js stack ->uncaught TypeError: Cannot read property 'language' of undefined error. Previous versions also encountered the Cannot read property 'AbortController' of undefined error, which only occurred when switching to the MQTT version

robertsLando commented 1 month ago

Follow steps here: https://github.com/mqttjs/MQTT.js#wechat-mini-program

TL;DR;

import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only' // import before mqtt.
import 'esbuild-plugin-polyfill-node/polyfills/navigator'
const mqtt = require("mqtt");
const client = mqtt.connect("wxs://test.mosquitto.org", {
  timerVariant: 'native' // more info ref issue: https://github.com/mqttjs/MQTT.js/issues/1797
});
AppSkyBoy commented 1 month ago

I have try import esbuild-plugin-polyfill-node and abortcontroller-polyfill module, but the same error is still reported. which is not running in WeChat or Alibaba mini programs. I directly package and run it on a real Android device through uni-app

AppSkyBoy commented 1 month ago

MQTT5.9.0 /5.9.1

10:04:10.476 reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught TypeError: Cannot read property 'language' of undefined at (app-service.js:5275:23) at (app-service.js:4873:22) at (app-service.js:5396:3) at (app-service.js:4873:22) at (app-service.js:6433:5) at (app-service.js:4873:22) at (app-service.js:6445:3) at (app-service.js:4873:22) at (app-service.js:22622:3) at (app-service.js:4878:19)

MQTT 5.8.1 wx:// protocl

11:20:22.498 [Vue warn]: Error in onLaunch hook: "Error: Node.js net module is not supported by JSPM core outside of Node.js"

(found at App.vue:1) 11:20:22.509 Error: Node.js net module is not supported by JSPM core outside of Node.js

MQTT 5.8.1 ws:// protocl

11:22:07.842 [Vue warn]: Error in onLaunch hook: "Error: ws does not work in the browser. Browser clients must use the native WebSocket object"

(found at App.vue:1) 11:22:07.854 Error: ws does not work in the browser. Browser clients must use the native WebSocket object

robertsLando commented 1 month ago

@AppSkyBoy I know you are not using wechat/ali, I just suggested you to use the same solution descrived there in order to fix the error above, wou should not use wx or ali protocol neighter but ws or wss instead. I have no clue of how your applications is built so I cannot help you so much here, seems one od your error comes from App.vue so I think you have vite that bundles it?

AppSkyBoy commented 1 month ago

Thank you very much for your help. MQTT can be packaged and used normally when switched to 4.1.0, and only the wx protocol can be used on the app, not the ws protocol, as WebSocket does not seem to be supported on Android apps. I am using uni app to package MQTT projects for Android applications( https://uniapp.dcloud.net.cn/ ). After MQTT4.1.0, using the wx protocol will result in the following errors: 18:21:49.483 [Vue warn]: Error in onLaunch hook: "TypeError: net.createConnection is not a function" (found at App.vue:1) 18:21:49.495 TypeError: net.createConnection is not a function When developing MQTT, you can consider packaging Uniapp as an Android app for compatibility, as there is still a high demand for this aspect

robertsLando commented 1 month ago

I have try import esbuild-plugin-polyfill-node and abortcontroller-polyfill module, but the same error is still reported. which is not running in WeChat or Alibaba mini programs. I directly package and run it on a real Android device through uni-app

Did you also run npm install to install those modules??

AppSkyBoy commented 1 month ago

I did not install those modules, only the MQTT module

robertsLando commented 1 month ago

@AppSkyBoy that's why it's not working, you have to also install them

AppSkyBoy commented 1 month ago

After MQTT 4.1.0 version, I installed those modules and the protocol remained unchanged, still using the wx protocol. The following errors also occurred: 18:21:49.483 [Vue warn]: Error in onLaunch hook: "TypeError: net.createConnection is not a function" (found at App.vue:1) 18:21:49.495 TypeError: net.createConnection is not a function This should be a compatibility issue with the network communication module. The network communication module of the wx protocol may be different before MQTT 4.1.0 and after 4.1.0. Before MQTT 4.1.0, another network communication module may by used, not net.createConnection. net.createConnection module seems to be unique to Node.js. When packaging, it is not possible to package the net module in to Android devices

robertsLando commented 1 month ago

@AppSkyBoy You have to use mqtt latest version (5.9.1 as ok today), install the polifilly modules mentioned aboce and add those imports mentioned above and it will work as described on docs. Mqtt 4 has been released more then 3 years ago and is not supported anymore

AppSkyBoy commented 1 month ago

However, when I use MQTT5.9.0 /5.9.1 or 5.8.1 respectively, there will be packaging errors:

MQTT5.9.0 /5.9.1

10:04:10.476 reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught TypeError: Cannot read property 'language' of undefined at (app-service.js:5275:23) at (app-service.js:4873:22) at (app-service.js:5396:3) at (app-service.js:4873:22) at (app-service.js:6433:5) at (app-service.js:4873:22) at (app-service.js:6445:3) at (app-service.js:4873:22) at (app-service.js:22622:3) at (app-service.js:4878:19)

MQTT 5.8.1 wx:// protocl

11:20:22.498 [Vue warn]: Error in onLaunch hook: "Error: Node.js net module is not supported by JSPM core outside of Node.js"

(found at App.vue:1) 11:20:22.509 Error: Node.js net module is not supported by JSPM core outside of Node.js

MQTT 5.8.1 ws:// protocl

11:22:07.842 [Vue warn]: Error in onLaunch hook: "Error: ws does not work in the browser. Browser clients must use the native WebSocket object"

(found at App.vue:1) 11:22:07.854 Error: ws does not work in the browser. Browser clients must use the native WebSocket object

I have installed these moudle : import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only' // import before mqtt. import 'esbuild-plugin-polyfill-node/polyfills/navigator' import mqtt from 'mqtt'; and just run this code:

const client = mqtt.connect("wxs://test.mosquitto.org", {
  timerVariant: 'native' // more info ref issue: #1797
});
robertsLando commented 1 month ago

seems like you bundler is not using the correct mqtt version. try ot use declarative import:

import mqtt from 'mqtt/dist/mqtt.esm'

AppSkyBoy commented 1 month ago

you can just new a "Hello uni-app" project whith Hbuilder, And make a simple demo with MQTT.js , Run on the real phone. Then you will find it doesn't work. It seems like compile error or packaging error

AppSkyBoy commented 1 month ago

[AD] 17:13:21.786 uni-cdn, saving you at least 30% on CDN costs! Detail 17:13:21.804 Project 'MQTT' start compiling... 17:13:22.929 3.8.4 17:13:22.932 Please note that in running mode, due to log output, sourcemap, and uncompressed source code, the performance and package size are not as good as release mode. 17:13:22.935 ​已开启 uni统计2.0 版本​ 17:13:22.941 ​【重要】因 HBuilderX 3.4.9 版本起,uni统计2.0 调整了安卓端 deviceId 获取方式,导致 uni统计2.0 App-Android平台部分统计数据不准确。如使用了HBuilderX 3.4.9 - 3.6.4版本且开通了uni统计2.0的应用,需要使用HBuilderX3.6.7及以上版本重新发布应用并升级 uniAdmin 云函数解决,详见:https://ask.dcloud.net.cn/article/40097​ 17:13:22.987 Compiling... 17:13:23.671 ​Browserslist: caniuse-lite is outdated. Please run: 17:13:23.673 npx update-browserslist-db@latest 17:13:23.677 Why you should do it regularly: https://github.com/browserslist/update-db#readme​ 17:13:35.477 App startup mode: fast. For details, see: https://ask.dcloud.net.cn/article/36749 17:13:56.998 The following css is not supported in nvue. If the global or public style is affected, it is recommended to write the warning style in the conditional compilation of ifndef APP-PLUS-NVUE. The details are as follows: 17:13:57.005 ​WARNING: min-width is not a standard property name (may not be supported) at uni_modules/uni-badge/components/uni-badge/uni-badge.vue:41​ 17:13:57.014 ​WARNING: font-feature-settings is not a standard property name (may not be supported) at uni_modules/uni-badge/components/uni-badge/uni-badge.vue:51​ 17:13:58.787 Project 'MQTT' compiled successfully. 17:13:58.921 Connecting device... 17:13:59.134 Mobile app playground is already installed, version is 3.8.4, version is not changed, skip update 17:14:01.462 Synchronizing app resources... 17:14:04.699 Synchronizing app resources completed 17:14:05.933 Starting mobile app playground HBuilder... 17:14:06.918 应用未关联服务空间,请在uniCloud目录右键关联服务空间 17:14:06.940 Application [MQTT] started. Note that there are errors in the compilation stage. Some modules may not be available 17:14:07.376 应用未关联服务空间,请在uniCloud目录右键关联服务空间 17:14:07.483 reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught TypeError: Cannot read property 'language' of undefined at (app-service.js:61409:23) at (app-service.js:61007:22) at (app-service.js:61530:3) at (app-service.js:61007:22) at (app-service.js:62567:5) at (app-service.js:61007:22) at (app-service.js:62579:3) at (app-service.js:61007:22) at (app-service.js:78756:3) at (app-service.js:61012:19)