The applet connects to MQTT for communication (guaranteed to work)

1. Introduction to MQTT communication

MQTT is a message transmission protocol based on the publish/subscribe mode of the client server architecture. Its design philosophy is lightweight, open, simple, standardized, and easy to implement. These characteristics make it a good choice for many scenarios, especially for constrained environments such as machine-to-machine communication (M2M) and Internet of Things (IoT) environments

Keyword explanation :
subscribe: Subscribe to a topic, and all messages received by this topic will be sent to you in the future

publish: Send a message to a topic, as long as the client subscribes to this topic, it will receive this message

Payload: the data sent, the general data format is string, hex (hexadecimal string), json, which is agreed by the front and back ends

QoS: Divided into three levels, 0: deliver at most once, 1: deliver at least once, 2: only deliver once
Among them, using QoS 0 may lose messages, using QoS 1 can guarantee receiving messages, but messages may be repeated, use QoS 2 can guarantee that messages are neither lost nor duplicated. The QoS level from low to high not only means the improvement of message reliability, but also the increase of transmission complexity.

Retain: will message, after the client subscribes to a topic, it will send the last message before this topic.
Applicable scenarios: For example, a temperature sensor is set to send temperature data every 1 hour. It happens that an app wants to display the temperature sensor data. When the app is opened, it just misses the last time the temperature sensor sent data. Under normal circumstances You need to wait another hour, but if you set the message to Retain, after the app is opened, you can still receive the data sent by the temperature sensor last time

2. Preparations for using mqtt in small programs

微信公众平台配置mqtt接口地址,必须是加密版的socket
insert image description here

3. The applet uses mqtt.js (does not support sending hexadecimal buffer messages)

Git address: https://github.com/mqttjs/MQTT.js

insert image description here

4.1.0 version js file download, directly give the address, save you wasting time to find
Link: https://pan.baidu.com/s/1_PxO9znYvssHF8oDgZB3ag?pwd=g63l
Extraction code: g63l

import mqtt from "../../utils/mqtt4.1.0.js"

  /**mqtt连接,不支持发送16进制buffer数据,暂弃用*/
  connectmqtt() {
    
    
    var that = this
    const options = {
    
    
      keepalive: 30,
      //protocolVersion: 4, //MQTT V3.1.1
      connectTimeout: 4000,
      clientId: 'sdfkskr43',//这个地方最好用一个随机字符串方法生成
      //port: 8084,
      username: '',
      password: '',
    }
    //此处需要用wxs,请注意!!!
    client = mqtt.connect(`wxs://xx.com/mqtt`, options)
    client.on('connect', (e) => {
    
    
      console.log('服务器连接成功', e)
      client.subscribe('abc', {
    
     qos: 2 }, function (err) {
    
    
        if (!err) {
    
    
          console.log('订阅成功', err)
        }
      })
    })
    //信息监听
    client.on('message', function (topic, massage) {
    
    
      console.log('收到' + this.ab2hex(massage))
    })
    client.on('reconnect', (error) => {
    
    
      console.log('正在重连', error)
    })
    client.on('error', (error) => {
    
    
      console.log('连接失败', error)
    })
    // 连接断开后触发的回调 
    client.on("close", function () {
    
    
      console.log("已断开连接")
    });
    // 客户端脱机下线触发回调 
    client.on("offline", function () {
    
    
      console.log("您已断开连接,请检查网络")
    });
    //当客户端发送任何数据包时发出。这包括publish()以及MQTT用于管理订阅和连接的包 
    client.on("packetsend", (packet) => {
    
    
      //console.log("客户端已发出报文", packet);
    });
  },
  //mqtt发送数据,只支持string,不支持16进制buffer
  mqttSend(msg) {
    
    
    client.publish('abc', msg, {
    
     qos: 2 }, function (err) {
    
    
      console.log('send', err)
    })
  },
  /**将ArrayBuffer转换成字符串*/
  ab2hex(buffer){
    
    
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
        function (bit) {
    
    
          return ('00' + bit.toString(16)).slice(-2)
        }
      )
      return hexArr.join('');
  }

4. The applet uses paho-mqtt-min.js (supports sending hexadecimal buffer messages)

Git address: https://github.com/eclipse/paho.mqtt.javascript

Official document address: https://www.eclipse.org/paho/files/jsdoc/Paho.MQTT.Client.html

js file download, directly give the address, save you wasting time to find, the official use of error reporting, this is a modified
link that can be used normally: https://pan.baidu.com/s/1TEEn2qT2M17KUXKC1CKccg?pwd=ged2
extraction Code: ged2

	var paho = require("../../utils/paho-mqtt-min.js");
	var client

   /**paho连接,支持发送16进制buffer数据*/
  connectPaho() {
    
    
    client = new paho.Client('wss://xx.com/mqtt', 'dfsdwfsdfsd'); //后面这个字符串可以用一个随机字符串方法随机生成
    var connectOptions = {
    
    
      //invocationContext: { host: "broker.emqx.io", port: 8084, clientId: 'xcx_wdc_' + util.randomWord(false, 43) },
      timeout: 10,
      //useSSL: true,
      cleanSession: false, //实现QoS>0必须设置为false,代表不清除,是持久会话
      keepAliveInterval: 5,
      reconnect: false, //意外断开之后会重连,第一次1秒后重连,往后每次翻倍直到2分钟,后续保持2分钟
      mqttVersion: 4,
      userName: '',
      password: '',
      onSuccess: function () {
    
    
        console.log('连接成功');
        client.onMessageArrived = function (msg) {
    
    
          //所有接收的消息都在这里,相关消息的业务处理都写在这里
          var message = this.ab2hex(msg.payloadBytes)
          console.log(message)
        }
        client.subscribe('abc', {
    
     qos: 2 });
      },
      onFailure: function (option) {
    
    
        console.log('fail', option)
      }
    }
    client.connect(connectOptions)
  },
  //paho发送数据,支持发送16进制buffer
  pahoSend(modbus) {
    
    
    var message = new paho.Message(this.string2buffer(modbus))
    message.destinationName = 'abc'
    message.qos = 2
    message.retained = false
    client.send(message)
  },
  /**将ArrayBuffer转换成字符串*/
  ab2hex(buffer){
    
    
    var hexArr = Array.prototype.map.call(
      new Uint8Array(buffer),
        function (bit) {
    
    
          return ('00' + bit.toString(16)).slice(-2)
        }
      )
      return hexArr.join('');
  },
  /**将16进制转化为ArrayBuffer*/
  string2buffer(str){
    
    
    return new Uint8Array(str.match(/[\da-f]{2}/gi).map(function (h) {
    
    
      return parseInt(h, 16)
    })).buffer
  },
  //切换后台断开
  onHide() {
    
    
    client.disconnect()
  },
  //切换前台重连
  onShow() {
    
    
    this.connectPaho()
  },

Five, real machine test error problem solving

可以看下我上面的代码,所有地址后面都没有带端口,其实之前写的都是xx.com:8084/mqtt,微信开发者工具上面测试是正常的,但是安卓真机测试就报错,比如AMQJSC0001E Connect timed out,这是因为安卓真机上面解析地址的时候,默认wss都是访问443端口,根本不会访问8084端口,咋不报错?这个时候就需要后端帮忙设置下nginx代理,默认443端口下的/mqtt访问,自动跳转到8084端口,代码如下:

    server {
    
    
        listen       443 ssl;
        server_name  localhost;

        ssl on;
        ssl_certificate      /var/lib/nginx/ssl/xx.pem;
        ssl_certificate_key  /var/lib/nginx/ssl/xx.key;

        ssl_session_timeout 5m;
        ssl_session_cache shared:SSL:10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2 SSLv3;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers on;
        ssl_verify_client off;

         location /mqtt {
    
    
             proxy_pass https://localhost:8084;
             proxy_http_version 1.1;
             # 最后两行的set_header表示将http协议头升级为websocket协议
             proxy_set_header Sec-WebSocket-Protocol mqtt;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection "upgrade";
         }
     }

nginx这样配置之后,小程序mqtt连接的端口就不需要写了,自动会访问443端口下的/mqtt,然后转到8084端口,这样就正常了,还有问题可以后面留言

Guess you like

Origin blog.csdn.net/LuoHuaX/article/details/129278224