更新记录

0.0.1(2025-12-16) 下载此版本

mqttjs@3.0.0的小程序和移动端优化版本


平台兼容性

uni-app(4.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟
- - - - - - - - - -

honshen-mqtt

增加了mqttjs@3.0.0在小程序和移动端的适配

  1. 修改了/lib/connect/ws.js

    socketTask = wx.connectSocket({
       url: url,
       protocols: websocketSubProtocol,
       success: (res) => {
         // 必须有success,fail,compelete函数才会返回socketTask对象
       },
     });
  2. 修改了/lib/client.js

    var setImmediate =
     global.setImmediate ||
     function (callback) {
       // 兼容所有 Web 环境的微任务替换
       Promise.resolve().then(callback);
     };

使用方法和mqtt一致

  1. 安装依赖 npm install honshen-mqtt@3.0.0

  2. 在代码文件中使用,这里以阿里云的mqtt微服务举例,需自行修改替换MQTT_CONFIG,_calcClientId,_calcHost 中对应的阿里云配置为实际的配置

    // import mqtt from 'mqtt/dist/mqtt.min';
    import mqtt from 'honshen-mqtt/dist/mqtt.min';
    import CryptoJS from 'crypto-js'; // 计算阿里云 MQTT 签名(小程序/App/H5 通用)
    // ==================== 全局配置(根据实际服务器修改)====================
    const MQTT_CONFIG = {
       // 唯一 ClientID(需保证全局唯一,加随机字符串避免重复)
       accessKey: '', // 阿里云 AccessKey
       secretKey: '', // 阿里云 SecretKey
       instanceId: '', // 阿里云 MQTT 实例 ID
       keepalive: 60, // 心跳间隔(秒)
       clean: true, // 清理会话(断开后是否保留订阅)
       reconnectPeriod: 5000, // 重连间隔(毫秒)
       connectTimeout: 5000,
       protocolVersion: 4, // MQTT 3.1.1(跨端兼容最佳)
       maxConnectedTime: 1000 * 60, // 最大连接时长,超过后会断开链接
    };
    
    // ==================== 工具类 ====================
    export class MQTTClient {
       client: any = null
       clientId = ''
       host = ''
       devicesStore: any = null
       onMessage: any
       constructor() {
           this.client = null;
       }
       private _generateUUID(): string {
           const hexDigits = '0123456789abcdef';
           let uuid = '';
           for (let i = 0; i < 36; i++) {
               if (i === 8 || i === 13 || i === 18 || i === 23) {
                   uuid += '-';
               } else if (i === 14) {
                   uuid += '4';
               } else if (i === 19) {
                   uuid += hexDigits.substr(Math.floor(Math.random() * 4) + 8, 1);
               } else {
                   uuid += hexDigits.substr(Math.floor(Math.random() * 16), 1);
               }
           }
           return uuid;
       }
    
       /**
          * 计算阿里云 clientId
          * @param {string} userId - 用户 ID
          * @returns {string} clientId
          */
       _calcClientId() {
           // 这个groupId需要替换为阿里云mqtt的groupId
           return `groupId@@@${this._generateUUID()}`;
       }
    
       /**
        * 计算阿里云 MQTT 签名(HMAC-SHA1 + Base64)
        * @param {string} clientId - 客户端 ID
        * @param {string} secretKey - 阿里云 SecretKey
        * @returns {string} 签名后的密码
        */
       _calcSignature(clientId: string, secretKey: string) {
           const hmac = CryptoJS.HmacSHA1(clientId, secretKey);
           return CryptoJS.enc.Base64.stringify(hmac);
       }
       _calcHost() {
           // 需要替换为阿里云的websocket mqtt的域名,协议开头是wxs
           return 'wxs://xxx:443/mqtt'
       }
    
       /**
        * 连接 MQTT 服务器
        * @returns {Promise} 连接结果(resolve: 成功, reject: 失败)
        */
       connect({ userId, onMessage, onConnect }: any) {
           return new Promise((resolve, reject) => {
               try {
                   this.disconnect();
                   this.clientId = this._calcClientId()
                   const clientId = this.clientId;
                   this.host = this._calcHost()
                   // 1. 计算签名(阿里云 MQTT 密码)
                   const password = this._calcSignature(clientId, MQTT_CONFIG.secretKey);
    
                   // 2. 构造连接选项
                   const options = {
                       clientId,
                       username: `Signature|${MQTT_CONFIG.accessKey}|${MQTT_CONFIG.instanceId}`,
                       password,
                       keepalive: MQTT_CONFIG.keepalive,
                       clean: MQTT_CONFIG.clean,
                       reconnectPeriod: MQTT_CONFIG.reconnectPeriod,
                       protocolVersion: MQTT_CONFIG.protocolVersion,
                       connectTimeout: MQTT_CONFIG.connectTimeout,
                   };
                   // 3. 连接 MQTT 服务器
                   this.client = mqtt.connect(this.host, options);
    
                   // 4. 监听连接成功
                   this.client.on('connect', () => {
                       resolve(true);
                   });
    
                   // 5. 监听连接失败
                   this.client.on('error', (err: any) => {
                       console.error('utils.MQTTClient[MQTT 连接error]', err);
                       reject(err);
                   });
    
                   // 6. 监听连接断开
                   this.client.on('close', () => {
                       console.error('utils.MQTTClient[MQTT 连接close]', this.clientId);
                   });
    
                   this.client.on('end', () => {
                       console.log('utils.MQTTClient[MQTT 连接end]', this.clientId);
                   });
                   this.client.on('disconnect', () => {
                       console.log('utils.MQTTClient[MQTT 连接disconnect]', this.clientId);
                   });
                   // 7. 监听重连
                   this.client.on('reconnect', () => {
                       console.log('utils.MQTTClient[MQTT 连接reconnect]', this.clientId);
                   });
    
                   // 8. 监听消息(全局事件总线传递给页面)
                   this.client.on('message', (topic: any, payload: any) => {
                       console.log(`utils.MQTTClient收到消息 - 主题: ${topic}, 内容: ${payload.toString()}`);
    
                   });
               } catch (e) {
                   console.error(`utils.MQTTClient连接失败`, e)
                   reject(e)
               }
           });
       }
    
       /**
        * 订阅主题
        * @param {string|array} topic - 订阅的主题(单个或数组)
        * @param {object} options - 订阅选项(如 qos: 0/1/2)
        * @returns {Promise} 订阅结果
        */
       subscribe(topic: string, options = { qos: 0 }) {
           return new Promise((resolve, reject) => {
               if (!this.client?.connected) {
                   return reject(false);
               }
    
               this.client.subscribe(topic, options, (err: any) => {
                   if (err) {
                       return reject(err);
                   } else {
                       resolve(true);
                   }
               });
           });
       }
    
       /**
        * 发布消息
        * @param {string} topic - 发布的主题
        * @param {string|buffer} payload - 消息内容
        * @param {object} options - 发布选项(如 qos: 0/1/2)
        * @returns {Promise} 发布结果
        */
       publish(topic: string, payload: any, options = { qos: 0 }) {
           return new Promise((resolve, reject) => {
               if (!this.client?.connected) {
                   reject(false);
                   return;
               }
               if (!payload) {
                   reject(false);
                   return;
               }
               this.client.publish(topic, payload, options, (err: any) => {
                   if (err) {
                       reject(err);
                   } else {
                       resolve(true);
                   }
               });
    
           });
       }
    
       /**
        * 取消订阅
        * @param {string|array} topic - 取消订阅的主题(单个或数组)
        * @returns {Promise} 取消订阅结果
        */
       unsubscribe(topic: string) {
           return new Promise((resolve, reject) => {
               if (!this.client?.connected) {
                   reject(false);
                   return;
               }
               this.client.unsubscribe(topic, (err: any) => {
                   if (err) {
    
                       reject(err);
                   } else {
                       resolve(true);
                   }
               });
           });
       }
    
       /**
        * 断开 MQTT 连接
        */
       async disconnect(force = true) {
           if (!this.client) {
               return false;
           }
           this.client.options.reconnectPeriod = 0;
           this.client.removeAllListeners && this.client.removeAllListeners();
           this.client.end(force, {}, (err: any) => {
               console.log(`utils.MQTTClient断开mqtt连接callback`, this.clientId, err);
           });
           console.log(`utils.MQTTClient断开mqtt连接成功`, this.clientId);
           this.client = null;
       }
    }
    

    使用

    let mqttClient: MQTTClient = new MQTTClient();
    let mqttConnectPromise: any = null;
    export const mqttConnect = async () => {
       mqttConnectPromise = mqttClient.connect({ });
       return mqttConnectPromise;
    }
    const init = async()=>{
       await mqttConnect();
       await mqttClient.subscribe('topic/sub-topic');
       await mqttClient.publish('topic/sub-topic', [1])
    }
    init();
    

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。