引言
虽然我的课主要是OpenHarmony南向开发的,但是结课时有个同学说他在写鸿蒙APP时无法将MQTT库加入到设备中,希望我帮忙看看。由于他没有鸿蒙的真机,只能用DevEco Studio中通过的模拟器来实现,而自带的模拟器只支持API9和API6,而下载的MQTT库是支持API11的。今天就来说说在API9中如何实现MQTT客户端,使用的DevEco Studio版本是3.11。
安装MQTT软件包
官方有个MQTT软件包:ohpm/mqtt,我写作时最新的版本是2.14,针对的是API12。虽然可以将其降级为2.0.5-rc.0或者2.0.6使其支持API9,但是由于其是从C语言版本移植过来的,依赖C语言的库文件(.so),而官方仓库中只提供了ARM版本的,所以在真机上可以用,但是在基于x86的本机模拟器上没法用,会出现"Failure[ERR_INSTALL_PARSE_NATIVE_SO_FAILED]"错误。如果要使用就需要使用SDK重新编译C语言文件产生x86可以用的库文件,有点麻烦。
今天推荐使用paho-mqtt: paho-mqtt移植,这个库是从js版本移植过来的,没有C语言编译的问题。当然这个库的限制是其使用的是websocket通信,因此只支持ws或wss开头的websocket连接方式的MQttBooker服务。 好在现在支持wss的服务器比较多,像巴法云、华为IoTDA、emqx都支持,因为小程序多使用wss。
安装软件包,可以在Terminal中使用如下命令:
ohpm install @yyz116/paho-mqtt
安装后要修改oh_modules/@yyz116/paho-mqtt/src/main/module.json文件,将其中的minAPIVersion和targetAPIVersion版本号都改为9。
{
"app": {
"bundleName": "com.yyz116.paho.mqtt",
"debug": true,
"versionCode": 1000000,
"versionName": "1.0.0",
"minAPIVersion": 9,
"targetAPIVersion": 9,
"apiReleaseType": "Release",
"compileSdkVersion": "5.0.0.65",
"compileSdkType": "HarmonyOS",
"appEnvironments": [],
"bundleType": "app"
},
"module": {
"name": "library",
"type": "har",
"deviceTypes": [
"default",
"tablet"
],
"packageName": "@yyz116/paho-mqtt",
"installationFree": false,
"virtualMachine": "ark12.0.2.0",
"compileMode": "esmodule",
"dependencies": []
}
}
避免MQTT软件包自动升级
上面的操作中修改了module.json文件,但是当三方包发布新版本后,点击同步工程,会出现默认更新安装的三方包版本情况。为了避免这种情况,手工修改oh-package.json5,将其中@yyz116/paho-mqtt一行版本号前面的"^"符号删除掉,这样保证安装固定版本的三方包。
{
"name": "myapplication",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
"@yyz116/paho-mqtt": "^1.0.1"
},
"devDependencies": {
"@ohos/hypium": "1.0.6"
},
"dynamicDependencies": {}
}
程序的编写
我编写了一个简单的测试程序,在前面先加上引用。
import MQTT from '@yyz116/paho-mqtt'
然后在按钮点击的事件函数中加入代码:
buttonClick()
{
let client = new MQTT.Client("bemfa.com", 9504, "/wss",
"xxxxxxxx");
client.trace = msg => {
console.log(msg.message);
};
client.connect({
timeout: 10,
keepAliveInterval: 60,
cleanSession: true,
useSSL: true,
// invocationContext: {
// asdf: true,
// },
onSuccess: o => {
//console.log("connected: ", o.invocationContext.asdf);
console.log("connected: ");
promptAction.showToast({
message: '连接到服务器!' //弹窗内容
});
client.send("light002", "123456", 0, true);
},
mqttVersion: 3,
onFailure: e => {
console.error("could not connect: ", e.errorMessage);
promptAction.showToast({
message: '无法连接到服务器!' //弹窗内容
});
},
reconnect: false,
});
}
这里需要注意巴法云加密websocket协议端口:9504 ,path:/wss。这和TCP端口是不同的。
为程序加入访问网络的权限,修改src/main/module.json5文件,加入requestPermissions这一段。
......
"pages": "$profile:main_pages",
"requestPermissions": [
{
"name": "ohos.permission.INTERNET",
"usedScene": {
"when": "always"
}
}
],
"abilities": [
......
运行测试
启动模拟器,运行程序如下。点击Connect按钮就可以了。
登录到巴法云后台,可以看到light002设备的值已经被更新。
结语
至此,基本完成了在API9和x86模拟器上运行MQTT客户端的要求。如果各位有更好的办法,欢迎留言。