微信小程序集成和使用mqtt(同时支持uniapp和原生)

前言

       在集成mqtt到小程序的开发过程中,确实走了不少弯路,下了许许多多的示例,一步步踩坑到现在终于完美解决了小程序引入mqtt的方法。该方法原生和uniapp均适用。

1. 小程序网页配置

先登录微信公众平台,找到开发》开发管理》开发设置页面

微信小程序集成和使用mqtt(同时支持uniapp和原生)_第1张图片

 

服务器域名配置中 配置socket合法域名为,mq消息服务器的域名。然后保存退出。

2.代码集成

1.新建mqtt文件夹,下载paho-mqtt.js,把这个js放在新建的文件夹下。

下载地址https://download.csdn.net/download/qq_35921773/33237463  

2.然后新建mqtt.js用来初始化自己的连接信息

把mqtt.js和paho-mqtt.js放在同级文件夹下。这样方便引入

let Paho = require('./paho-mqtt.js');
var mqtt = {};
//client对象
var client = null;
//mqtt连接对象
const mqttUrl = {
    hostname: "xxx.cn",
    port:8084,
    path: "/mqtt"
}
 
//订阅的主题与回掉方法
var map = new Map();
 
/**
 * mqtt 连接状态
 * 0:正在连接
 * 1:连接成功建立
 * 2:连接正在关闭
 * 3:连接已经关闭
 */
let connectStatus = 0;
 
//初始化weboscket
mqtt.initMqtt = () => {
    if (null == client) {
        //创建mqtt客户端
        client = new Paho.Client(mqttUrl.hostname, Number(mqttUrl.port), mqttUrl.path, 'wxapp_client_'+Math.random(),);
    } else {
        //Do-nothing
    }
 
    client.onConnected = (reconnect, uri) => {
        console.log("mqtt连接成功!client:", reconnect, uri);
        //连接成功
        connectStatus = 1;
        //注册全局的报警事件
    }
 
    client.onConnectionLost = (responseObject) => {
        console.log("mqtt连接关闭!", responseObject);
        if (responseObject.errorCode != 0) {
            //异常关闭
            mqtt.initMqtt();
        } else {
            //正常关闭连接
        }
        connectStatus = 3;
    }
 
 
 
    client.onMessageArrived = (message) => {
        //console.log("Message Recieved: [Topic: ", message.destinationName, ", Payload: ", message.payloadString, ", QoS: ", message.qos, ", Retained: ", message.retained, ", Duplicate: ", message.duplicate, "]");
        let topic = message.destinationName;
        //console.log("map:",map);
        try {
            let msgObj = {}
            new Promise((resolve, reject) => {/* executor函数 */
                msgObj = JSON.parse(message.payloadString);
                resolve(msgObj);
            }).catch(function (value) {
                console.log('JSON转化异常')
                return;
            });
            if(topic.indexOf('$SYS/brokers/')>-1){
                map.get('home')(topic,msgObj);
            }else if(topic.indexOf('/client')>-1){
                map.get('device')(topic,msgObj);
            }
        } catch (err) {
            console.error(err);
        }
 
    }
 
 
    var options = {
        invocationContext: {
            host: mqttUrl.hostname,
            port: mqttUrl.port,
            path: mqttUrl.path,
            clientId: 'wxapp_client_'+Math.random(),
        },
        //超时
        timeout: 5,
        //心跳
        keepAliveInterval: 60,
        //清除session,如果不清除,重连之后还能收到订阅的数据
        cleanSession: true,
        useSSL:true,
        reconnect: true,
        onSuccess: onConnect,
        onFailure: onFail
    };
 
    function onConnect(context) {
        console.log("mqtt连接成功context:", context)
        //连接成功
        connectStatus = 1;
    }
 
    function onFail(context) {
        console.log("mqtt连接失败onFail:", context)
        mqtt.initMqtt();
    }
 
    if (1 != connectStatus) {
        console.log("开始连接");
        client.connect(options);
        //正在建立连接
        connectStatus = 0;
    }
 
 
}
 
 
/**
 * 订阅主题
 * topic:主题名称
 * qos:服务质量
 */
mqtt.subscribe = function(topic, qos, receiveCallback) {
    if (1 == mqtt.getStatus()) {
        client.subscribe(topic, {
            qos: Number(qos)
        });
        if(topic.indexOf('$SYS/brokers/')>-1){
            map.set('home',receiveCallback);
        }else if(topic.indexOf('/client')>-1){
            map.set('device',receiveCallback);
        }
    } else {
        setTimeout(function() {
            mqtt.subscribe(topic, qos, receiveCallback);
        }, 1000)
    }
}
 
/**
 * 取消订阅主题
 * topic:主题名称
 */
mqtt.unsubscribe = function(topic) {
    if (1 == mqtt.getStatus()) {
        client.unsubscribe(topic, {
            onSuccess: unsubscribeSuccess,
            onFailure: unsubscribeFailure,
            invocationContext: {
                topic: topic
            }
        });
        map.delete(topic);
    } else {
        setTimeout(function() {
            mqtt.unsubscribe(topic);
        }, 1000)
    }
}
 
function unsubscribeSuccess(context) {
    console.log("取消订阅成功Topic:", context.invocationContext.topic);
}
 
function unsubscribeFailure(context) {
    console.log("取消订阅成功Topic:", context.invocationContext.topic);
    setTimeout(function() {
        mqtt.unsubscribe(context.invocationContext.topic);
    }, 1000)
}
 
/**
 * 发送消息
 * message:消息内容
 * topic:主题
 * qos:服务质量
 */
mqtt.publish = function(message, topic, qos) {
    if (1 == mqtt.getStatus()) {
        var message = new Paho.Message(message);
        message.destinationName = topic;
        message.qos = Number(qos);
        message.retained = false;
        client.send(message);
        wx.showToast({
            title: '发送成功'
        })
    } else {
        wx.showToast({
            title: '正在重新连接服务器,请稍后重试',
            icon: 'none',
            duration: 2000
        })
        setTimeout(function() {
            mqtt.publish(message, topic, qos);
        }, 1000)
    }
}
 
 
/**
 * 返回mqtt的连接状态
 */
mqtt.getStatus = function() {
    return connectStatus;
}
 
 
 
/**
 * 关闭连接
 */
mqtt.disconnect = function() {
    console.log("关闭mqtt连接");
    if (null != client) {
        client.disconnect();
    } else {
        //Do-nothing
    }
    connectStatus = 3;
    client = null;
}
 
mqtt.initMqtt();
 
export default mqtt;

3.页面使用

import mqtt from '../../common/utils/mqtt.js'
//指向刚才新建的mqtt.js
 
//onLoad初始化订阅
onLoad(option) {
   mqtt.subscribe('$SYS/brokers/+/clients/#', 0, this.receiveCallback); 
},
 
methods: {
    //收到消息后的回调
     receiveCallback(){
          console.log('addad')
     },
}

 内外网切换BAT脚本

1. 切换内网脚本

微信小程序集成和使用mqtt(同时支持uniapp和原生)_第2张图片

BAT脚本设置IP、子网掩码、网关、DNS

@echo off
cls
color 0A
Echo *******************************************************************************
Echo           正在修改IP地址和DNS服务器地址,请耐心等待…………
Echo *******************************************************************************
cmd /c netsh interface ip set address name="以太网" source=static addr=27.195.110.187 mask=255.255.255.0 gateway=27.195.110.254 gwmetric=1
cmd /c netsh interface ip set dns "以太网" static 26.195.232.1 primary
ipconfig /all
Echo *******************************************************************************
Echo          OK!!已修改成功!请按任意键继续…………
Echo *******************************************************************************

2. 切换外网脚本(IP自动获取)

@echo off
cls
color 0A
Echo *******************************************************************************
Echo           正在修改IP地址和DNS服务器地址,请耐心等待…………
Echo *******************************************************************************
netsh interface ip set address name="以太网 4" source=dhcp
netsh interface ip delete dns "以太网 4" all
ipconfig /flushdns
ipconfig /all
Echo *******************************************************************************
Echo          OK!!已修改成功!请按任意键继续…………
Echo *******************************************************************************

 

你可能感兴趣的:(微信小程序,uni-app,小程序)