支付宝小程序作对外开放,有许许多多的好玩的地方,那么本文就在支付宝小程序上websocket实现mqtt协议连接服务器控制智能硬件!!
那么本系列连载的博文,都是围绕着 支付宝小程序如何实现控制 esp8266 为主线的!
初接触支付宝小程序,,毕竟听前辈说这个可以支持个人开发了,很顺畅地注册成功了!开始研究其结构,因为我是比较熟悉微信小程序开发的,看到支付宝的demo我一下子就觉得这个和微信小程序差不多的!
直到晚上9点半,我看到 GitHub 有一个 MQTT.js 库支持 支付宝小程序 mqtt的协议实现,我像是打了胰岛素一样非常兴奋,意味着我们 支付宝小程序可以控制智能设备 了,而且容易实现!
这晚上我折腾到了凌晨12点半,早上九点还要上班呢。所幸的是,我在虚拟机(支付宝开发工具 提供)上运行并连接服务器成功了!之后我调试到真机也行了!但预览连接失败?但是我内心还是兴奋的,毕竟虚拟机是成功哇!!
早上带熊猫眼上班,总结凌晨的开发预览到 真机就失败?我在想是不是 ios 和 android 的机子问题?于是乎我换个 ios 手机,一样地还是预览失败!按照以往的开发经验,是否 未检查域名? 还是不对!于是乎我 ios 报错的截图拿给了 支付宝小程序开发官方钉钉群里面。报错是 某个类未定义,如下截图:
前面说了这么多东西,下面开始讲本博文的主要内容吧!
官网注册:支付宝开放平台 自己支付宝APP扫描登录申请!
官网的结构开发文档:小程序文档 - 支付宝文档中心
开发工具的调试功能 有调试、预览,可以编译到虚拟机模拟器上,也可以调试和预览到真机,但是必须打开支付宝app!上传功能是把这次开发的版本放在服务器,服务器可以提供二维码给测试人员使用!
查看日志打印,点击最下面的“调试”按钮,就可以看到调试日志了,包括自己的 console.log 日志!
具体的开发API文档使用demo,支付宝也有提供了,在创建工程时候,有个模版选择,大家可以试下选择他,熟悉下开发的结构!
再次声明,请勿在模拟器上调试websocket !!
我们知道, mqtt 只是一种协议,而我们 websocket 是负责通讯的底层,它是在 前端JavaScript上实现的长连接 通讯。类似我们的 tcp 长连接,当我们清楚地知道这个原理之后。我们仅仅负责如何收发数据的逻辑就可以了!
服务器上,我还是使用 EMQ 。而支付宝小程序我使用的是仍然是 GitHub上面一个出名的库:GitHub - mqttjs/MQTT.js: The MQTT client for Node.js and the browser 。主要是因为他已经是实现了 数据的生成和解析。
wss
或者 ws
,但是如果上架,那就必须是 wss
了 ! my.connectSocket({
url: url,
success: (res) => {
console.log('connect url: ' + url)
},
fail:(res)=>{
console.log('connect fail:'+JSON.stringify(res))
}
})
//打开 socket
my.onSocketOpen(function (res) {
stream.setReadable(proxy)
stream.setWritable(proxy)
stream.emit('connect')
})
//被动关闭 socket 的回调
my.onSocketClose(function (res) {
console.log('WebSocket onSocketClose !' + res);
stream.end()
stream.destroy()
})
//打开 socket错误回调!
my.onSocketError(function (res) {
stream.destroy(res)
})
//监听到socket的数据下发回调
my.onSocketMessage((res) => {
//这里主要是对数据的判断,因为有时候是字符串,有时候是数组!
if (typeof res.data === 'string') {
var array = base64.toByteArray(res.data)
var buffer = Buffer.from(array)
proxy.push(buffer)
} else {
var reader = new FileReader()
reader.addEventListener('load', function () {
var data = reader.result
if (data instanceof ArrayBuffer) data = Buffer.from(data)
else data = Buffer.from(data, 'utf8')
proxy.push(data)
})
reader.readAsArrayBuffer(res.data)
}
});
base64
编码,之后再传给 sendSocketMessage
,以及在形参 isBuffer
赋值为 true
表示当前发送是 buffer 数组,之后 SDK 会自动处理反解密发送出去!//senddata 是经过base64加密的arry数组
my.sendSocketMessage({
data: senddata,
isBuffer:true,
success: function (res) {
next()
},
fail: function (res) {
next(new Error())
}
})
const host = 'alis://www.domain.cn:443/mqtt';
配置:
options: {
protocolVersion: 4, //MQTT连接协议版本
clientId: 'alis Mini',
myAli: null,
clean: true,
password: 'xuhong123456',
username: 'admin',
reconnectPeriod: 1000, //1000毫秒,两次重新连接之间的间隔
connectTimeout: 30 * 1000, //1000毫秒,两次重新连接之间的间隔
resubscribe: true //如果连接断开并重新连接,则会再次自动订阅已订阅的主题(默认true)
}
this.data.client = mqtt.connect(host, this.data.options);
this.data.client.on('connect', function (connack) {
my.showToast({ content: "连接成功", type: 'success' })
})
//服务器下发消息的回调
that.data.client.on("message", function (topic, payload) {
console.log(" 收到 topic:" + topic + " , payload :" + payload)
my.showToast({ content: " 收到topic:[" + topic + "], payload :[" + payload + "]", type: 'success' })
})
//服务器连接异常的回调
that.data.client.on("error", function (error) {
console.log(" 服务器 error 的回调" + error)
my.showToast({ content: "连接服务器失败,错误信息:" + error, type: 'exception', })
})
//服务器重连连接异常的回调,一般是域名或者服务器不存在
that.data.client.on("reconnect", function () {
console.log(" 服务器 reconnect的回调")
my.showToast({ content: "连接服务器失败,正在重连...", type: 'exception', })
})
//服务器连接异常的回调
that.data.client.on("offline", function (err) {
console.log(" 服务器offline的回调"+JSON.stringify(err))
})