初始化一个mpvue项目
1.使用命令生成项目
vue init mpvue/mpvue-quickstart connectaliyun
2.使用webStorm打开该项目
3.安装依赖
npm install
4.生成微信项目
npm start
5.使用微信开发工具导入项目
6.配置项目
把不需要的删掉
7.使用stylus
npm install stylus --save-dev
npm install stylus-loader --save-dev
<style lang="stylus" rel="stylesheet/stylus">
8.做一些基础页面设计
客户端基本配置
1.下载nodejs版mqtt.js
npm install mqtt --save
2.下载crypto密码类库
npm install crypto --save
3.创建一个js文件
用于获取连接所需信息
我把最后文件放在末尾
创建阿里云iot产品
1.创建产品
2.添加设备
3.获取三元组
连接阿里云方法一
1.填入三元组参数
2.调用连接函数
3.调试时遇到问题,,,,,
mpvue关于vendor.js大于500kb
解决办法:
找到项目下的build文件夹,打开webpack.dev.conf.js文件
var UglifyJsPlugin = require('uglifyjs-webpack-plugin') // 头部引入
module.exports = merge(baseWebpackConfig, {
// ...
plugins: [
// ...
new UglifyJsPlugin({ sourceMap: true }) // 加入这个就能解决
]
})
4.又遇到问题
心累,不调这个了
.
.
.
.
.
.
5.问题解决
问题产生的原因参考下面方法二的第3点
此方法我就不继续实现了,都大同小异
感兴趣的可以去mqtt-npm看一看相关的api
连接阿里云方法二
阿里云官方文档
https://help.aliyun.com/document_detail/96618.html?spm=a2c4g.11186623.2.18.11502cf0i2WSGj
1.安装阿里云依赖
npm install alibabacloud-iot-device-sdk --save
2.创建三元组信息
(该方法不行参考下面第4点)
//创建iot.device对象将会发起到阿里云IoT的连接
const device = iot.device({
productKey: '<productKey>', //将<productKey>修改为实际产品的ProductKey
deviceName: '<deviceName>',//将<deviceName>修改为实际设备的DeviceName
deviceSecret: '<deviceSecret>',//将<deviceSecret>修改为实际设备的DeviceSecret
});
3.一如既往的失败
当博客写到这的时候,我已经折腾了一天了。
这个错误是:
WS is not a constructor; [Component] Event Handler Error @ pages/test/test#bound toconnect
TypeError: WS is not a constructor
我本以为,照着阿里云官方文档能很顺利的完成这个过程,但是没想到折腾了一天,并且上面node.js版本的mqtt也有类似的错误,
不过后来我再去读node.js时才看到这个细节,node.js版原来给出了一定的提示,不过我当时可没发现这个细节
不卖关子了,其实就是请求时的url的问题,如果是微信小程序,协议必须是wxs://否则就会一直出错,而且根本找不到相关资料…,
如果直接调用iot.device他就会直接去连接,但是协议不是wxs://所以就会直接报错,那么解决方法呢,就是不使用iot.device,而是使用使用mqtt.mqtt();
4.获取用户信息
创建一个getAliyunInfo.js文件,完整代码放最后
const crypto = require('./crypto')
export function getInfo(){
const deviceConfig = {
productKey: "替换",
deviceName: "替换",
deviceSecret: "替换",
regionId: "cn-shanghai"
}
const options = initMqttOptions(deviceConfig);
return {
url:'wxs://'+deviceConfig.productKey+'.iot-as-mqtt.'+deviceConfig.regionId+'.aliyuncs.com',
options:options
}
}
5.连接并订阅主题
var client = mqtt.mqtt.connect(this.url,this.options), receiveMsg;
receiveMsg = this.receiveMsg
client.on('connect',()=>{
this.receiveMsg += "连接服务器成功\n";
client.subscribe(this.topic.receiveTopic,function (err) {
if(!err){
console.log('订阅主题成功');
receiveMsg += "订阅主题成功\n";
}else
{
console.log("订阅主题失败\n"+err);
receiveMsg += "订阅主题失败\n";
}
})
订阅成功
使用阿里云控制台发送消息
小程序获取到消息
6.发布消息
注意信息的格式是Alink协议
message
{
"id": "123",
"version": "1.0",
"params": {
"LightSwitch": {
"value": 1,
"time": 1524448722000
},
"CurrentTemperature": {
"value": 18.3,
"time": 1524448722000
}
},
"method": "thing.event.property.post"
}
var client = this.client;
if(!client.connected){
client.connect(this.url,this.options);
}else {
client.publish(this.topic.publishTopic,this.message);
}
上报前
上报
上报后
总结
1.创建mpvue项目
2.读阿里云或mqtt-npm的文档
3.注意connect(url,opts),中的url协议是wxs://
4.调试,完成
代码
获取加密后的连接信息
const crypto = require('crypto');
const deviceConfigs = {
productKey: "替换",
deviceName: "替换",
deviceSecret: "替换",
regionId: "cn-shanghai"
}
//获取处理后的配置信息,
//调用该方法可以获取 url,options,deviceInfo
export function getConfigInfo(){
const options = initMqttOptions(deviceConfigs);
return {
deviceConfig:deviceConfigs,
url:'wxs://'+deviceConfigs.productKey+'.iot-as-mqtt.'+deviceConfigs.regionId+'.aliyuncs.com',
options:options
}
}
//IoT平台mqtt连接参数初始化
function initMqttOptions(deviceConfig) {
const params = {
productKey: deviceConfig.productKey,
deviceName: deviceConfig.deviceName,
timestamp: Date.now(),
clientId: Math.random().toString(36).substr(2),
}
//CONNECT参数
const options = {
keepalive: 60, //60s
clean: true, //cleanSession不保持持久会话
protocolVersion: 4 //MQTT v3.1.1
}
//1.生成clientId,username,password
options.password = signHmacSha1(params, deviceConfig.deviceSecret);
options.clientId = `${params.clientId}|securemode=2,signmethod=hmacsha1,timestamp=${params.timestamp}|`;
options.username = `${params.deviceName}&${params.productKey}`;
return options;
}
/*
生成基于HmacSha1的password
参考文档:https://help.aliyun.com/document_detail/73742.html?#h2-url-1
*/
function signHmacSha1(params, deviceSecret) {
let keys = Object.keys(params).sort();
// 按字典序排序
keys = keys.sort();
const list = [];
keys.map((key) => {
list.push(`${key}${params[key]}`);
});
const contentStr = list.join('');
return crypto.createHmac('sha1', deviceSecret)
.update(contentStr)
.digest('hex');
}
index.vue
<template>
<div id="container">
<input v-model="message">
<button @click="hello">发送信息</button>
<label for="showtext" >接收消息</label>
<textarea id="showtext" v-text="receiveMsg" ></textarea>
</div>
</template>
<script>
var ConfigInfo = require( "../../../static/utils/ConnectAliYunUtils");
var mqtt = require( '../../../static/utils/alibabacloud-iot-device-sdk-1.2.8-alimin-compatible');
export default {
created: function () {
console.log("created");
var info = ConfigInfo.getConfigInfo();
this.url = info.url;
this.options = info.options;
this.deviceInfo = info.deviceConfig;
this.topic = {
publishTopic: '/sys/a1UICYcmZJp/wechatMiniApp/thing/event/property/post',
receiveTopic:'/'+this.deviceInfo.productKey+'/'+this.deviceInfo.deviceName+'/user/get'
}
var client = mqtt.mqtt.connect(this.url,this.options), receiveMsg;
receiveMsg = this.receiveMsg
client.on('connect',()=>{
this.receiveMsg += "连接服务器成功\n";
client.subscribe(this.topic.receiveTopic,function (err) {
if(!err){
console.log('订阅主题成功');
receiveMsg += "订阅主题成功\n";
}else
{
console.log("订阅主题失败\n"+err);
receiveMsg += "订阅主题失败\n";
}
})
})
client.on('message',(topic, payload)=>{
this.receiveMsg += "message:\n"+"payload:"+payload+'\n';
})
this.client = client;
},
data() {
return {
message:'{\n' +
' "id": "123",\n' +
' "version": "1.0",\n' +
' "params": {\n' +
' "LightSwitch": {\n' +
' "value": 1,\n' +
' "time": 1524448722000\n' +
' },\n' +
' "CurrentTemperature": {\n' +
' "value": 38.6,\n' +
' "time": 1524448722000\n' +
' }\n' +
' },\n' +
' "method": "thing.event.property.post"\n' +
'}',
receiveMsg:' ',
client:{},
url:'',
options:'',
deviceInfo:'',
topic:{
publishTopic:'',
receiveTopic:''
}
}
},
methods:{
hello(){
var client = this.client,messageConsole;
messageConsole = this.receiveMsg
if(!client.connected){
client.connect(this.url,this.options);
this.receiveMsg += '连接服务器中\n'
}else {
client.publish(this.topic.publishTopic,this.message,function (error) {
if (!error){
console.log('发布成功')
messageConsole += '发布成功\n'
}
});
}
}
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus">
#container
input
height:80rpx
width 100%
padding-left 10rpx
border 1rpx solid green
font-size 50rpx
button
background coral
color white
textarea
border 1rpx solid green
width 100%
height 200rpx
padding 10rpx
font-size 50rpx
</style>