• 支付宝小程序集成MQTT


    支付宝小程序集成MQTT

    1. 前言

    由于支付宝只支持websocket连接,在尝试了很多npm安装mqtt亦或是使用paho-mqtt.js、重新编译过后的mqtt.js多方无果后,最终决定自己做一个桥接的websocket服务,来作为mqtt的Borker和小程序的websocket的中转服务。最终实现了支付宝小程序可以收到和发送mqtt消息的目的。
    2023-09-06 终于在网上找到了可以使用mqtt直连支付宝小程序的demo,所以在他的基础上我进行了整合,当然使用本篇的websocket中转也可以实现mqtt收发消息的功能。相对而言,感觉websocket的方式还是稳定性高的,想使用mqtt直连的可以直接参考下一篇。
    支付宝小程序集成mqtt兼容IOS和安卓

    2. 处理流程

    1. 搭建一个springboot的简易版websocket服务端,同时连接mqtt的Broker作为mqtt的客户端。简称中转服务。
    2. 小程序使用websocket连接中转服务。
    3. 小程序发送websocket服务到中转服务,中转服务把收到的消息发送给mqtt的Broker。
    4. 中转服务收到mqtt发送的消息,查找对应的websocket小程序用户唯一id是否存在。如果存在就通过websocket发送给小程序。
    5. 小程序收到websocket消息,做对应的处理。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ​ 本章主要介绍支付宝小程序的处理方式,下一章介绍如何搭建springboot的中转服务。

    3. 接口详情

    1. wss地址
      这里是我们自己搭建的中转服务websocket地址。

      wss://xxxx.cn/netgate/密钥/pid/sn/openid
      
      • 1
    2. 参数说明

      参数名称参数说明
      密钥自定义标识符,用于鉴权处理
      pid设备产品ID【设备二维码中包含此信息】
      sn设备序列号【设备二维码中包含此信息】
      openid用户自己的id。可以使用个人平台的用户唯一id。相同ID会挤掉前一个用户的ws连接

    4. 代码详解

    小程序示例UNIAPP方式

    如果没有使用uniapp框架,使用原生技术
    微信小程序: 需要把uni.替换成wx.

    支付宝小程序:需要把uni.替换成my.

    1. 新建ws.js文件

    var ws = {};
    const wsUrl= 'wss://xxxx.cn/netgate/密钥/';
    var timeoutObj;
    let connectStatus = 0;
    //避免socket重复连接
    let lockReconnect = false;
    function heartCheck(){
        console.log('准备心跳检测')
        if(timeoutObj){
            clearInterval(timeoutObj);
        }
        timeoutObj = setInterval(function () {
             uni.sendSocketMessage({
                data: 'H', // 需要发送的内容
                success: (res) => {
                    console.log('心跳O(∩_∩)O')
                },
            });
        }, 55000)
    }
    ws.initWs = (pid,sn,openid) => {
        uni.onSocketOpen(function() {
            // uni.showToast({title: 'WebSocket 连接已打开!'})
            console.log('WebSocket 连接已打开!');
            connectStatus = 1;
            heartCheck()
        });
        uni.onSocketError(function(res){
            // uni.showToast({title: 'WebSocket 连接打开失败,请检查!'})
            console.log('WebSocket 连接打开失败,请检查!');
            ws.reconnect()
        });
        uni.onSocketClose((res) => {
            uni.showToast({title: '连接已关闭'})
            ws.reconnect()
            console.log('连接已关闭')
        });
        uni.offSocketClose((res)=>{
            uni.showToast({title: '取消监听 WebSocket 关闭事件'})
            console.log('取消监听 WebSocket 关闭事件')
            connectStatus = 0;
        });
        uni.offSocketError((res) =>{
            uni.showToast({title: '取消监听 WebSocket 错误事件'})
            console.log('取消监听 WebSocket 错误事件')
            connectStatus =0;
        });
        uni.offSocketOpen((res)=>{
            uni.showToast({title: '取消监听 WebSocket 连接打开事件'})
            console.log('取消监听 WebSocket 连接打开事件')
            connectStatus = 0;
        });
        uni.offSocketMessage((res)=>{
            uni.showToast({title: '取消监听 WebSocket 接收到服务器的消息事件'})
            console.log('取消监听 WebSocket 接收到服务器的消息事件')
        });
        uni.connectSocket({
            url: wsUrl+ pid+ '/' +sn+ '/'+ openid,
            success: (res) => {
                console.log('连接成功')
                uni.showToast({title: '设备连接成功'})
            },
            fail:(res)=>{
                console.log('connect fail:'+JSON.stringify(res))
            }
        })
    }
    ws.disconnect = ()=> {
        console.log('关闭ws连接')
        uni.closeSocket()
        // 链接关闭后切断所有监听
        // 支付宝小程序的ws连接问题,关闭连接时需关闭对于接受,防止关闭失败
        uni.offSocketMessage();
        uni.offSocketError();
        uni.offSocketOpen();
        uni.offSocketClose();
    }
    ws.reconnect = ()=> {
        console.log('正在准备重新连接')
        if (lockReconnect) return;
        console.log('重新连接')
        lockReconnect = true;
        let self = this;
        setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
            self.connect();
            lockReconnect = false;
        }, 2000);
    }
    
    ws.sendMsg = function(msg) {
        console.log('准备发送消息')
        uni.sendSocketMessage({
            data: msg, // 需要发送的内容
            success: (res) => {
                console.log('消息发送成功==='+msg)
            },
        });
    }
    
    export default ws;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101

    2. 页面使用

    <script>
        import ws from "../../common/utils/ws";
     	export default {
              onUnload(){
              	 ws.disconnect()
              },
              onLoad(){
                ws.initWs(this.curProId,this.curSn,userInfo.wxid)
                let self = this;
                uni.onSocketMessage(function(res) {
                    self.deviceReceiveMsgWs(res.data)
                }) 
              },
              methods: {
                  //接收消息
              	 deviceReceiveMsgWs(msgStr){
                    console.log('ws收到了消息'+msgStr)
                 },
                  //发送消息
                 sendMsg(){
                     ws.sendMsg('{"CMD":"STATE"}')
                 }
              }
        }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    5. 下一篇

    springboot集成websocket

    springboot集成mqtt

  • 相关阅读:
    nginx
    基于Django + Web + MySQL的智慧校园系统
    如何使用界面控件Telerik UI for WinForms过滤数据?这里有答案
    给面试加点硬菜:延迟任务场景,该如何提高吞吐量和时效性!
    C/C++后端开发学习路线总结(附带实习学习经历分享)
    通过Go语言创建CA与签发证书
    小白文——计算机网络如何学??
    lesson-2C++类与对象(中)
    字符串5——左旋转字符串
    图解设计模式——Iterator模式(一个一个遍历)
  • 原文地址:https://blog.csdn.net/qq_35921773/article/details/127451886