微信小程序--P2P消息收发模式(MQTT)

news2024/11/20 14:21:17

目录

前言

js demo

参数

new Paho.Client 创建对象

onConnectionLost  连接丢失回调

onMessageArrived  监听数据

connect (connectOptions)将此消息客户端连接到其服务器。

mqtt 频繁断开和重连问题

小程序实践


前言

P2P,顾名思义,是一对一的消息收发模式,即只有一个消息发送者和一个消息接收者。而Pub/Sub模式通常用于一对多或多对多的消息群发场景,即拥有一个或多个消息发送者和多个消息接收者的场景。

在P2P模式中,发送者发送消息时已经明确该消息预期的接收者信息,并明确该消息只需要被特定的单个客户端消费。发送者发送消息时通过Topic信息直接指定接收者,接收者无需提前订阅即可获取该消息。

P2P模式不仅可以为接收者节省注册订阅关系的成本,此外,由于收发消息的链路有单独的优化,还可以降低推送延迟。

参考文档 :P2P消息收发模式(MQTT)

https://help.aliyun.com/document_detail/96176.html?spm=a2c4g.11186623.2.13.229f42caHWXK5fhttps://help.aliyun.com/document_detail/96176.html?spm=a2c4g.11186623.2.13.229f42caHWXK5f参考文档 :P2P消息收发模式 .Client.

https://www.eclipse.org/paho/files/jsdoc/Paho.MQTT.Client.htmlhttps://www.eclipse.org/paho/files/jsdoc/Paho.MQTT.Client.html参考文档  paho-mqtt基础库

https://github.com/AwakenCN/InChat/blob/paho-mqtt/wechat-client/utils/paho-mqtt.jshttps://github.com/AwakenCN/InChat/blob/paho-mqtt/wechat-client/utils/paho-mqtt.js

js demo

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Aliyun Mqtt Websockets</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js" type="text/javascript"></script>
    <script type="text/javascript">
        instanceId = 'XXXX';//实例 ID,购买后从控制台获取
        host = 'XXXX.mqtt.aliyuncs.com';// 设置当前用户的接入点域名,接入点获取方法请参考接入准备章节文档,先在控制台创建实例
        port = 80;//WebSocket 协议服务端口,如果是走 HTTPS,设置443端口
        topic = 'XXXX';//需要操作的 Topic,第一级父级 topic 需要在控制台申请
        useTLS = false;//是否走加密 HTTPS,如果走 HTTPS,设置为 true
        accessKey = 'XXXXX';//账号的 AccessKey,在阿里云控制台查看
        secretKey = 'XXXXX';//账号的的 SecretKey,在阿里云控制台查看
        cleansession = true;
        groupId = 'GID_XXXX';//MQTT GroupID,创建实例后从 MQTT 控制台创建
        clientId = groupId + '@@@00001';//GroupId@@@DeviceId,由控制台创建的 Group ID 和自己指定的 Device ID 组合构成
        var mqtt;
        var reconnectTimeout = 2000;
        var username = 'Signature|' + accessKey + '|' + instanceId;//username和 Password 签名模式下的设置方法,参考文档 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7
        var password = CryptoJS.HmacSHA1(clientId, secretKey).toString(CryptoJS.enc.Base64);

        function MQTTconnect() {
            mqtt = new Paho.MQTT.Client(
                host,//MQTT 域名
                port,//WebSocket 端口,如果使用 HTTPS 加密则配置为443,否则配置80
                clientId//客户端 ClientId
            );
            var options = {
                timeout: 3,
                onSuccess: onConnect,
                mqttVersion: 4,
                cleanSession: cleansession,
                onFailure: function (message) {
                    setTimeout(MQTTconnect, reconnectTimeout);
                }
            };
            mqtt.onConnectionLost = onConnectionLost;
            mqtt.onMessageArrived = onMessageArrived;
            if (username != null) {
                options.userName = username;
                options.password = password;
                options.useSSL = useTLS;//如果使用 HTTPS 加密则配置为 true
            }
            mqtt.connect(options);
        }

        function onConnect() {
            // Connection succeeded; subscribe to our topic
            //发送 P2P 消息,topic 设置方式参考https://help.aliyun.com/document_detail/96176.html?spm=a2c4g.11186623.6.586.694f7cb4oookL7
            message = new Paho.MQTT.Message("Hello mqtt P2P Msg!!");//set body
            message.destinationName = topic + "/p2p/" + clientId;// set topic
            mqtt.send(message);
        }

        function onConnectionLost(response) {
            setTimeout(MQTTconnect, reconnectTimeout);
        };

        function onMessageArrived(message) {
            var topic = message.destinationName;
            var payload = message.payloadString;
            console.log("recv msg : " + topic + "   " + payload);
        };
        MQTTconnect();
    </script>
</head>
</html>

参数

new Paho.Client 创建对象

JavaScript应用程序使用Paho.MQTT.Client对象与服务器通信。

大多数应用程序只创建一个Client对象,然后调用其connect()方法,但是如果需要,应用程序可以创建多个Client对象。在这种情况下,每个客户端对象的主机、端口和clientId属性的组合必须不同。

发送、订阅和取消订阅方法被实现为异步JavaScript方法(即使底层协议交换本质上可能是同步的)。这意味着它们通过调用应用程序(通过应用程序提供的有关方法的成功或失败回调函数)来发出完成的信号。这种回调在每个方法调用中最多调用一次,并且不会持续到调用脚本的生命周期之外。

相比之下,Paho.MQTT.Client对象上定义了一些回调函数,尤其是onMessageArrived。这些方法可能会被多次调用,并且与客户端进行的特定方法调用没有直接关系。

  • host字符串消息服务器的地址,作为完全限定的WebSocket URI,作为DNS名称或虚线十进制IP地址。
  • port number要连接到的端口号-仅当主机不是URI时才需要
  • path字符串要连接到的主机上的路径-仅当主机不是URI时使用。默认值:'/mqt'。
  • clientId字符串消息传递客户端标识符,长度在1到23个字符之间。

onConnectionLost  连接丢失回调

当连接丢失时调用。connect()方法成功后。建立连接丢失时使用的回调。连接可能会丢失,因为客户端启动了断开连接,或者因为服务器或网络导致客户端断开连接。例如,如果客户端无法连接,则可以在不调用connectionComplete回调的情况下调用disconnect回调。将单个响应对象参数传递给onConnectionLost回调,该回调包含以下字段:

  •  errorCode 错误代码
  • errorMessage 错误消息

onMessageArrived  监听数据

当消息到达此Paho.MQTT.客户端时调用。传递给onMessageArrived回调的参数为

  • destinationName强制消息要发送到的目的地的名称(对于即将发送的消息)或接收消息的目的地名称。(用于onMessage功能接收的消息)。
  • payloadString :只读如果有效负载包含有效的UTF-8字符,则将有效负载作为字符串
  • payloadBytes :只读作为ArrayBuffer的有效负载
  • qs:用于传递消息的服务质量。0最大努力(默认)。1至少一次。2正好一次。
  • retained:如果为true,则服务器将保留该消息,并将其传递给当前订阅和未来订阅。如果为false,则服务器仅将消息传递给当前订户,这是新消息的默认值。如果消息发布时保留的布尔值设置为true,并且在消息发布后进行了订阅,则收到的消息将保留的布尔设置为true。
  • duplicate :只读如果为true,则此消息可能与已接收的消息重复。这仅在从服务器接收的消息上设置。

connect (connectOptions)将此消息客户端连接到其服务器。

connectOptions用于连接的属性

  1. timeout : 如果在该秒数内连接未成功,则视为连接失败。默认值为30秒
  2. userName 此连接的身份验证用户名
  3. password:此连接的身份验证密码。
  4. onSuccess:当从服务器接收到连接确认时调用。单个响应对象参数传递给onSuccess回调,该回调包含以下字段: invocationContext传递给connectOptions中的onSuccess方法。
  5. cleanSession:清除会话  cleanif true(默认值)成功连接时删除客户端和服务器的持久状态。
  6. mqttVersion 用于连接到MQTT代理的MQTT版本。 3or4
  7. useSSL 如果存在且为真,请使用SSL Websocket连接。{如果使用 HTTPS 加密则配置为 true}
  8. onFailure:当连接请求失败或超时时调用。单个响应对象参数传递给onFailure回调,该回调包含以下字段: 
  • 传入connectOptions中onFailure方法的invocationContext。
  • errorCode表示错误性质的数字。
  • error描述错误的消息文本。

mqtt 频繁断开和重连问题

mqtt.js底层没有对你调用它方法传入的callback函数做异常捕获(你传入callback函数里面不做异常捕获,会导致mqtt底层代码逻辑异常,导致频繁断连&重连问题发生),所以你所有的callback函数都需要增加try..catch..方法捕获异常(比如发布,订阅,监听等方法调用的时候的第二个callback函数)

小程序实践

 const Paho = require('../../utils/mqtt');
 const CryptoJS = require('../../utils/crypto-js.js');
 let instanceId = 'XXXX';//实例 ID,购买后从控制台获取
 let host = 'XXXX.mqtt.aliyuncs.com';// 设置当前用户的接入点域名,接入点获取方法请参考接入准备章节文档,先在控制台创建实例
 let port = 80;//WebSocket 协议服务端口,如果是走 HTTPS,设置443端口
 let topic = 'XXXX';//需要操作的 Topic,第一级父级 topic 需要在控制台申请
 let useTLS = false;//是否走加密 HTTPS,如果走 HTTPS,设置为 true
 let accessKey = 'XXXXX';//账号的 AccessKey,在阿里云控制台查看
 let secretKey = 'XXXXX';//账号的的 SecretKey,在阿里云控制台查看
 let cleansession = true;
 let groupId = 'GID_XXXX';//MQTT GroupID,创建实例后从 MQTT 控制台创建
 let clientId = groupId + '@@@00001';//GroupId@@@DeviceId,由控制台创建的 Group ID 和自己指定的 Device ID 组合构成
 var mqtt;
 var reconnectTimeout = 2000;
 var username = 'Signature|' + accessKey + '|' + instanceId;//username和 Password 签名模式下的设置方法,参考文档 https://help.aliyun.com/document_detail/48271.html?spm=a2c4g.11186623.6.553.217831c3BSFry7
 var password = CryptoJS.HmacSHA1(clientId, secretKey).toString(CryptoJS.enc.Base64);

onLoad(options) {
 this.MQTTconnect()
},
// MQTT连接
  MQTTconnect() {
    try {
      let that = this
      //创建mqtt对象
      mqtt = new Paho.Client(
        host,//MQTT 域名
        port,//WebSocket 端口,如果使用 HTTPS 加密则配置为443,否则配置80
        clientId//客户端 ClientId
      );
      // 准备链接属性
      var options = {
        timeout: 3, //超时时间
        onSuccess: that.onConnect, //当从服务器接收到连接确认时调用
        mqttVersion: 4,//用于连接到MQTT代理的MQTT版本。
        cleanSession: cleansession,//清除会话  cleanif true(默认值)成功连接时删除客户端和服务器的持久状态。
        onFailure: function (message) {//当连接请求失败或超时时调用。
          console.log(message, "连接请求失败或超时。");
          setTimeout(that.MQTTconnect, reconnectTimeout);
        }
      };

      mqtt.onConnectionLost = that.onConnectionLost;  //连接丢失回调
      mqtt.onMessageArrived = that.onMessageArrived;  //监听数据回调

      if (username != null) {
        options.userName = username;//此连接的身份验证密码。
        options.password = password;//此连接的身份验证用户名s
        options.useSSL = useTLS;//如果使用 HTTPS 加密则配置为 true
      }
      //链接
      mqtt.connect(options);
    } catch (error) {

    }
  },
  //当从服务器接收到连接确认时调用
  onConnect() {
    try {
      // Connection succeeded; subscribe to our topic
      //发送 P2P 消息,topic 设置方式参考https://help.aliyun.com/document_detail/96176.html?spm=a2c4g.11186623.6.586.694f7cb4oookL7
      message = new Paho.Message("Hello mqtt P2P Msg!!");//set body
      message.destinationName = topic + "/p2p/" + clientId;// set topic
      mqtt.send(message);
    } catch (error) {

    }
  },
  //连接丢失回调
  onConnectionLost(response) {
    try {
      let that = this
      console.log("连接丢失了:" + response.errorCode + response.errorMessage)
      setTimeout(that.MQTTconnect, reconnectTimeout);
    } catch (error) {

    }
  },
  //监听数据
  onMessageArrived(message) {
    try {
      var topic = message.destinationName;
      var payload = message.payloadString;
      console.log("recv msg : " + topic + "   " + payload);
    } catch (error) {

    }
  },


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/112097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vTESTstudio入门到精通 - vTESTstudio工具栏介绍_Layout

到今天这一篇vTESTstudio工具栏介绍就将暂时告一段落了&#xff0c;后续如果大家有需求的话可以私信我&#xff0c;我就继续再往深的介绍&#xff0c;如果没有催更的话&#xff0c;就当这部分是给大家做个普及&#xff0c;作为一个扫盲篇吧&#xff0c;实际项目使用和编程的内容…

Nginx反向代理的一个算法API的接口调用超时:504,GateWay Timeout,怎么破?

背景 服务端由第三方部署了一个基于 darknet &#xff08;一个较为轻型的完全基于C与CUDA的开源深度学习框架&#xff09;的识别算法服务&#xff0c;通过 Flask 的 Web 服务对业务服务暴露 API 接口。作为测试&#xff0c;一开始是直接通过 python3 app.py 的命令行启动的服务…

SAP Product Lifecycle Costing 里的 Costing Sheet 成本核算表

有朋友在我的知识星球里向我提问&#xff1a; 请您帮忙讲一下这个AP0100的costing sheet rows这里都表示什么意思吗&#xff1f;比如row10、base Z010、overhead啥、描述、from、to row、credit都说明了什么&#xff0c;能够实现上面&#x1f446;&#x1f3fb;的目标吗&#x…

【详细学习SpringBoot源码之属性配置文件加载原理(Bootstrap.properties|Bootstrap.yml)-8】

一.知识回顾 【0.SpringBoot专栏的相关文章都在这里哟&#xff0c;后续更多的文章内容可以点击查看】 【1.SpringBoot初识之Spring注解发展流程以及常用的Spring和SpringBoot注解】 【2.SpringBoot自动装配之SPI机制&SPI案例实操学习&SPI机制核心源码学习】 【3.详细学…

Transformer图解

Transformer正在席卷自然语言处理领域。 这些令人难以置信的模型正在打破多项 NLP 记录并推动最先进的技术发展。 它们被用于许多应用程序&#xff0c;如机器语言翻译、会话聊天机器人&#xff0c;甚至为更好的搜索引擎提供动力。 Transformer在当今深度学习领域风靡一时&…

POSTGRESQL 13.1 bug 与 逻辑复制槽参数调优

随着问问题的同学越来越多&#xff0c;公众号内部私信回答问题已经很困难了&#xff0c;所以建立了一个群&#xff0c;关于各种数据库的问题都可以&#xff0c;目前主要是 POSTGRESQL, MYSQL ,MONGODB ,POLARDB ,REDIS&#xff0c;SQL SERVER 等&#xff0c;期待你的加入&#…

pytorch 多卡运行详细教程

先说明一下背景&#xff0c;目前正在魔改以下这篇论文的代码&#xff1a; https://github.com/QipengGuo/GraphWriter-DGLgithub.com 由于每次完成实验需要5个小时&#xff08;baseline&#xff09;&#xff0c;自己的模型需要更久&#xff08;2倍&#xff09;&#xff0c;非…

战略和什么相关?

&#xff08;1&#xff09;战略和创新企业做到最大&#xff0c;就是业务多元化/一体化、区域全球化。想再折腾折腾&#xff0c;那就手里这几张牌搞重新排列组合&#xff0c;这就是&#xff1a;企业再造。就是中国人说的&#xff1a;天下大势分久必合合久必分。按照波士顿咨询来…

20221224英语学习

今日词汇 lash v.将&#xff08;物品&#xff09;系牢&#xff0c;捆绑&#xff1b;&#xff08;风、雨等&#xff09;猛烈打击&#xff1b;鞭打&#xff1b;猛烈抨击&#xff0c;严厉斥责 detective n.侦探; 警探; 发掘者; 发现者 division n.分开; 分隔; 分配; 分隔物; 刻…

深度学习SSD算法

目录1 SSD网络结构1.1 backbone1.2 extra部分1.3 loc和cls1.3.1 PriorBox层先验框的生成方法1.3.2 loc的预测结果2 模型训练2.1 正负样本标记2.2 损失函数2.3 困难样本挖掘3 模型预测4 总结1 SSD网络结构 SSD是YOLO V1出来后&#xff0c;YOLO V2出来前的一款One-stage目标检测…

Linux0.11 考古笔记

Linux0.11 考古笔记 最近读完《Linux 内核完全注释》和《品读 Linux0.11 核心代码》&#xff0c;大致理解下 Linux0.11 内核的全貌。在我理解这些属于计算机基础类的知识&#xff0c;所以在未来的工作场景不太可能会直接用到它们&#xff0c;如果用不到的话这些知识可能会随着…

从 2022 年优秀 Linux 发行版中挑选你喜欢的版本

导读如果你想从 2022 年最佳 Linux 发行版列表中挑选一个最喜欢的版本&#xff0c;那么今天你需要考虑以下几个选项。 2022 年是充满惊喜的一年&#xff0c;Linux 发行版的表现也不例外。从充满功能的新版本到各种桌面选项&#xff0c;总有一些值得期待的东西。 如果你想从 20…

自制macOS安装镜像iso虚拟机用

在网上下载的用于在虚拟机中安装的镜像版本相对比较旧。安装完成后还要进行升级比较麻烦。于是我就想自己制作安装镜像了。 精华 #创建空白磁盘镜像 hdiutil create -o /tmp/ventura -size 13800m -volname ventura -layout SPUD -fs HFSJ #挂载上面创建的镜像 hdiutil attac…

【Java 数据结构】-二叉树OJ题

作者&#xff1a;学Java的冬瓜 博客主页&#xff1a;☀冬瓜的博客&#x1f319; 专栏&#xff1a;【Java 数据结构】 分享&#xff1a;宇宙的最可理解之处在于它是不可理解的&#xff0c;宇宙的最不可理解之处在于它是可理解的。——《乡村教师》 主要内容&#xff1a;二叉树的…

离职时,是在公司群里大方告别,主动退群?还是一言不发,默默退出?

离职时怎么体面退出工作群&#xff1f;一位网友说&#xff0c;自己公司的同事离职那天&#xff0c;在公司群里发了一大段感谢的话&#xff0c;大大方方挥手告别后主动退了群。有同事夸这个离职的人情商高&#xff0c;这样告别大方得体&#xff0c;是离职的好表率。但楼主觉得&a…

SAP UI5 加载本地并不存在的 PDF 文件的错误处理

这个 _onLoadListener 函数什么时候注册的呢&#xff1f; iframe 完成加载之后&#xff0c;就触发这个 load 事件注册的处理函数&#xff1a; PDFViewer.prototype.onAfterRendering function () {var fnInitIframeElement function () {// cant use attachBrowserEvent be…

vue后台管理系统项目-vue-quill-editor实现富文本编辑器功能 可直接使用

富文本编辑器功能实现详细过程 目录 富文本编辑器功能实现详细过程 1.安装富文本插件 2.实现效果 3.实现详细过程 可直接使用 全局引入 局部引入 配置option 扩展需求 自定义配置文字大小 1.安装富文本插件 npm install vue-quill-editor --save //或者 yarn add vu…

Android电源管理介绍

一、电源管理基础知识1.1电源管理的几种状态Android kernel源码中&#xff0c;定义了三种电源状态&#xff0c;在kernel/power/suspend.c中&#xff1a;对应的宏定义/include/linux/suspend.h1.2 电源管理状态的介绍&#xff1a;PM_SUSPEND_ON设备处于正常工作状态PM_SUSPEND_S…

VsCode搭建C语言运行环境以及终端乱码问题解决

在VsCode中搭建C/C运行环境需要先安装以下插件 1、安装c/c插件 2、安装code runner插件 当然也可以安装一些其他的美化插件根据个人习惯&#xff0c;但是以上这两个是必装的。 安装好插件后来到插件主页点击卸载旁边的小齿轮选择扩展设置 找到扩展设置中的下图选项并打上勾即可…

前端小知识:控制台打印(console)- 模拟Java日志打印、表格形式打印美化输出对象、代码运行时间统计

文章目录6. 控制台打印&#xff08;Console&#xff09;模拟Java日志打印格式美化对象打印&#xff08;表格形式打印输出&#xff09;日志等级输出&#xff08;让其在控制台显示时有颜色提示&#xff09;代码运行时间统计打印输出6. 控制台打印&#xff08;Console&#xff09;…