【消息中间件】原生PHP对接Uni H5、APP、微信小程序实时通讯消息服务

news2024/11/15 20:46:21

文章目录

  • 视频演示效果
  • 前言
  • 一、分析
  • 二、全局注入MQTT连接
    • 1.引入库
    • 2.写入全局连接代码
  • 二、PHP环境建立
  • 总结


视频演示效果

【uniapp】实现买定离手小游戏


前言

Mqtt不同环境问题太多,新手可以看下

  1. 《【MQTT】Esp32数据上传采集:最新mqtt插件(支持掉线、真机调试错误等问题》
  2. 《一篇就够:uniapp-Mqtt系列问题详细攻略(解决掉线、真机调试错误等问题)》
  3. 《解决微信小程序MQTT真机连接问题与合法域名配置SSL问题》
  4. 《解决微信小程序MQTT通讯真机调试失败的问题附加可用代码》
  5. 《Esp8266-01s、51单片机实现连接MQTT踩坑:附加烧录安信可固件+宝塔搭建MQTT服务器 全套攻略》

以上的就是我所有的Mqtt踩坑记录,相信看完应该能解决了,今天这一篇文章,主要是记录升级Mqtt5.0以及如何适配安卓端,如果不想看,也可以直接去下载插件:【uniapp】【5.0协议】最完整Mqtt示例代码(解决掉线、真机调试错误等问题)
注意:插件代码不含如果要用在app端,请留意评论区的消息,换协议
在这里插入图片描述

在这里插入图片描述


一、分析

将原APP接入实时通讯,采用MQTT,有很多优点,这里就不列举了。这次对接的是我的打卡平台,
分为三个端:H5、APP、微信小程序
要保证三个端都通,我这里也不绕圈子了,协议我会放在本节底部,通过uniapp中的app.vue文件,将mqtt连接为全局状态,无论哪个页面都不会掉线,那么如何一对一接收呢?这里我做的思路是将客户端的订阅号订阅名改为自己的登陆账号,也就是说,用户未登录时不连接,检测到用户登录后将账户结合一些制定字符串作为onTopic,服务端指定发送过去即可,分析完之后我们开始实现客户端的连接。
在这里插入图片描述

连接案例:

var hosts = '';
// #ifdef APP-PLUS
hosts = 'wx://' + that.globalData.serve.host + ':443/mqtt';
// #endif

// #ifdef H5
hosts = 'wss://' + that.globalData.serve.host + ':443/mqtt';
// hosts = 'wss://' + that.globalData.serve.host + ':443/mqtt';

// hosts = 'tcp://' + this.globalData.serve.host + ':' + this.globalData.serve.wsport + this.globalData.serve.path;
//#endif
// #ifdef MP-WEIXIN
// wx仅仅可以使用体验版
hosts = 'wxs://' + that.globalData.serve.host + ':443/mqtt';
//#endif

二、全局注入MQTT连接

1.引入库

import mqtt from '@/utils/mqtt3.0.0.js'; // 导入MQTT库

在这里插入图片描述

库直接在插件中下载即可用:
【uniapp】【5.0协议】最完整Mqtt示例代码(解决掉线、真机调试错误等问题)

2.写入全局连接代码

App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面入口文件。但App.vue本身不是页面,这里不能编写视图元素,也就是没有。

这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData

<script>  
    export default {  
        globalData: {  
            text: 'text'  
        }
    }  
</script>  

所以我们的代码:

<script>
  import mqtt from '@/utils/mqtt3.0.0.js'; // 导入MQTT库
    export default {
       globalData: {  
           serve: {
            host: 'mqtt.taila.club',
            wsport: '8083',
            wssport:'443',
            path: 'mqtt',
           },
           onTopic: '',//订阅发送来的消息
           onSub: '',//
           Qos: 2,
           sendMassage: '',
           time:0,
           receiveMessage: '',
           client: null,
           //MQTT连接的配置
           options: {
            wsOptions: {},
            protocolVersion: 5, //MQTT连接协议版本
            clientId: '',
            keepalive: 60,
            clean: false,
            username: '',
            password: '',
            reconnectPeriod: 1000, //1000毫秒,两次重新连接之间的间隔
            connectTimeout: 30 * 1000, //1000毫秒,两次重新连接之间的间隔
            resubscribe: true //如果连接断开并重新连接,则会再次自动订阅已订阅的主题(默认true)
           },
              },
      onLaunch: function() {
         let that=this;
         console.log('======'+that.globalData.Qos)
         // console.log('======'+that.globalData.Qos)
        // 先断开
        that.unconnect();
        console.log('App Launch')
        
        //版本检查
        //调用示例 配置参数, 默认如下,其中api是接口地址,必须填写
        // #ifdef APP-PLUS
      
        //
      
        //版本检查
      
        
        //mqtt
        // 检查本地存储是否存在登录状态的信息
        that.check_account_mqtt_connect();
        
      },
      methods: {
        subscribe: function() {
            // 判断是否已成功连接
            if (!this.globalData.client || !this.globalData.client.connected) {
              this.showToast('客户端未连接', 1000)
              return;
            }
        
            this.globalData.client.subscribe(this.globalData.onTopic, {
              qos: this.globalData.Qos
            }, error => {
              if (!error) {
                this.showToast('订阅成功', 1000, 'success')
                console.log('订阅成功');
              }
            });
        
            
          },
          publish: function() {
            // 判断是否已成功连接
            if (!this.globalData.client || !this.globalData.client.connected) {
              this.showToast('客户端未连接', 1000)
              return;
            }
            if (this.globalData.sendMassage != '') {
              // var send = '{"code": 200, "msg": "发送打1111指令", "data": "2.doc"}';
              
               // 定义JSON对象
                const messageq = {
                  code: 200,
                  msg: '发送打印指令',
                  data: '2.doc'
                }
              
                // 将JSON对象转换为JSON字符串
                const message1 = JSON.stringify(messageq)
              this.globalData.client.publish(this.globalData.onSub,message1, error => {
                console.log(error || '消息发布成功');
                this.showToast('消息发布成功', 1000, 'success')
              });
            } else {
              this.showToast('发布消息为空', 1000)
            }
        
          },
          unsubscribe: function() {
            this.globalData.client.unsubscribe(
              
              this.globalData.onTopic,
              err => {
                console.log(err || '取消订阅成功');
                this.showToast('取消订阅成功', 1000, 'success')
              }
            );
          },
          unconnect: function() {
            if (!this.globalData.client || !this.globalData.client.connected) {
              this.showToast('客户端未连接', 1000)
              return;
            }
            this.client.end();
            this.client = null
            this.showToast('成功断开连接', 1000, 'success')
            console.log('断开连接');
          },
          showToast: function(title, time, icon = 'none') {
            uni.showToast({
              title: title,
              icon: icon,
            });
            setTimeout(function() {
              uni.hideToast();
            }, time);
          },
        
        check_account_mqtt_connect:function(){
          let that=this;
          const openid = uni.getStorageSync('openid');
          
           if (openid=='') {
            uni.showToast({
              title:'订阅消息连接失败',
            icon:'none'
            })
           }else{
             // 如果存在登录状态的信息,直接进行MQTT连接
             //构造必要数据
             let clientId = "mqtt_" + Math.random().toString(16).substr(2, 8)+openid;
             console.log("生成的随机clientId为:" + clientId);
              this.globalData.options.clientId=clientId;
             this.globalData.onTopic=openid;//定义订阅消息
             that.connect();
           }
        },
      connect: function() {
        let that = this;
        var hosts = '';
        // #ifdef APP-PLUS
      hosts = 'wx://' + that.globalData.serve.host + ':443/mqtt';
        // #endif
        
        // #ifdef H5
        hosts = 'wss://' + that.globalData.serve.host + ':443/mqtt';
        // hosts = 'wss://' + that.globalData.serve.host + ':443/mqtt';
       
         // hosts = 'tcp://' + this.globalData.serve.host + ':' + this.globalData.serve.wsport + this.globalData.serve.path;
        //#endif
        // #ifdef MP-WEIXIN
        // wx仅仅可以使用体验版
      hosts = 'wxs://' + that.globalData.serve.host + ':443/mqtt';
        //#endif
        console.log(hosts);
        if (that.globalData.client == null || that.globalData.client.connented == false) {
          uni.showLoading({
            title: '连接中···'
          });
          that.globalData.client = mqtt.connect(
            hosts,
            that.globalData.options
          );
      
          that.globalData.client.on('connect', () => {
            uni.hideLoading();
            that.showToast('连接成功', 1000, 'success');
            that.subscribe();
          });
      
          that.globalData.client.on('message', (topic, message) => {
            console.log('收到来自' + topic + '的消息' + message.toString());
            uni.showToast({
              title:'收到一条消息:请在主页查收',
          duration:4000,
          icon:'none'
            })
            // 在收到消息时调用onMessageArrived回调函数进行处理
         
          });
        }
      
        that.globalData.client.on('reconnect', error => {
          uni.hideLoading();
          that.showToast('正在重连···', 1000);
        });
      
        that.globalData.client.on('error', error => {
          uni.hideLoading();
          that.showToast('连接失败!', 1000);
        });
      },
  
        
    
      },
      onShow: function() {
        console.log('App Show')
      },
      onHide: function() {
        console.log('App Hide')
      }
    }
</script>


<style lang="scss">
  /* ==== App.vue 文件 ==== */
    /* 为了避免电脑浏览器中的滚动条影响到布局,可在 style 标记中添加如下 CSS 代码*/
     
    /* 条件编译,仅在H5平台生效 */
    // #ifdef H5
    body::-webkit-scrollbar,html::-webkit-scrollbar {
        display: none;
    }
    // #endif
      /*每个页面公共css */
      @import "@/uni_modules/b-ui/css/main.bundle.scss";
</style>

注意:
App.vue和其他页面不一样,我也是弄了好久才弄清楚,另外使用了全局globalData才编译成小程序时最新版本会报错,获取不到,应该时BUG,我当时用的是基础组件2.33版本就解决了

二、PHP环境建立

下载文章顶部的配套资源到服务器
在这里插入图片描述
修改封装的代码里面的连接信息,以及数据持久化

<?php
require_once("php_mqtt/mqtt.class.php");//基础组件
function send_mqtt_message($receiver, $content,$conn,$type)
{
    $server = "mqtt.taila.club";  // 服务代理地址(mqtt服务端地址)
    $port = 1883;                // 通信端口
    $username = "";              // 用户名(如果需要)
    $password = "";              // 密码(如果需要)
    $client_id = "clientx9293670xxctr_492344"; // 设置你的连接客户端id

    $mqtt = new Mqtt($server, $port, $client_id); // 实例化MQTT类
    if ($mqtt->connect(true, NULL, $username, $password)) {
        // 如果创建链接成功
        $message = array(
            'message_id' => uniqid(), // 使用uniqid生成唯一的消息ID
            'sender' => '153***9', // 消息的发送者,可以是用户ID或用户名
            'receiver' => $receiver, // 消息的接收者,可以是用户ID或用户名
            'content' => $content, // 消息的内容,可以是文本、图片、文件等
            'timestamp' => time(), // 消息的时间戳,记录消息的发送时间
            'type' => $type, // 消息的类型,用于区分不同类型的消息0系统消息
            'status' => '0'//0未读1已读
        );

        $json_message = json_encode($message); // 将PHP数组转换为JSON字符串

        $mqtt->publish("$receiver", $json_message, 2); // 发送JSON消息到主题 "gg"
        //持久化
       // $sql="INSERT INTO `message` (`message_id`, `sender`, `receiver`, `content`, `type`, `status`, `create_time`) VALUES (NULL, '15368666279', '$receiver', '$content', '$type', '0', CURRENT_TIMESTAMP)";
       // $conn->query($sql);
        $mqtt->close(); // 发送后关闭链接
    } else {
        echo "Time out!\n";
    }
}
?>

调用方式非常简单,新建index.php

<?php
include '../../api/conn.php';//连接数据库根据你情况来定
require_once("../../api/Message_push/mqtt_sender.php");

//消息发送
$receiver = $_GET["openid"];//发送手机号
$content = $_GET["msg"];//发送的消息
send_mqtt_message($receiver, $content,$conn,'1');
?>

总结

以上就是今天要讲的内容,本文仅仅简单介绍了【MQTT5】原生PHP对接Uni H5、APP、微信小程序实时通讯消息服务的使用

🍋希望你能喜欢我的其他作品
《记一次云之家签到抓包》
《记一次视频抓包m3u8解密过程》
《抓包部分软件时无网络+过代理检测 解决办法 安卓黄鸟httpcanary+vmos》
《Python】记录抓包分析自动领取芝麻HTTP每日免费IP(成品+教程)》
《某课抓包视频 安卓手机:黄鸟+某课app+VirtualXposed虚拟框架》

推荐专栏:

《Python爬虫脚本项目实战》

该专栏往期文章:
《【Python爬虫项目实战一】获取Chatgpt3.5免费接口文末付代码(过Authorization认证)》

🥦如果感觉看完文章还不过瘾,欢迎查看我的其它专栏
🥦作者对python有很大的兴趣,完成过很多独立的项目:例如滇医通等等脚本,但是由于版权的原因下架了,爬虫这一类审核比较严谨,稍有不慎就侵权违规了,所以在保证质量的同时会对文章进行筛选

如果您对爬虫感兴趣请收藏或者订阅该专栏哦《Python爬虫脚本项目实战》,如果你有项目欢迎联系我,我会同步教程到本专栏!

🚀Python爬虫项目实战系列文章!!
⭐⭐欢迎订阅⭐⭐

【Python爬虫项目实战一】获取Chatgpt3.5免费接口文末付代码(过Authorization认证)
【Python爬虫项目实战二】Chatgpt还原验证算法-解密某宝伪知网数据接口

⭐⭐欢迎订阅⭐⭐
在这里插入图片描述

Python爬虫脚本项目实战
在这里插入图片描述

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

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

相关文章

GAMES101 笔记 Lecture13 光线追踪1

目录 Why Ray Tracing?(为什么需要光线追踪&#xff1f;)Basic Ray Tracing Algorithm(基础的光线追踪算法)Ray Casting(光线的投射)Generating Eye Rays(生成Eye Rays) Recursive(Whitted-Styled) Ray Tracing Ray-Surface Intersection(光线和平面的交点)Ray Rquation(射线方…

盘点:查快递教程

在“寄快递”成为常态的当下&#xff0c;如何快速进行物流信息查询&#xff0c;是收寄人所关心的问题。在回答这个问题之前&#xff0c;首先我们要知道&#xff0c;物流信息查询&#xff0c;有哪些方法&#xff1f; 1、官网单号查询 知道物流公司和单号的情况下&#xff0c;直…

管理类联考——写作——论说文——实战篇——标题篇

角度3——4种材料类型、4个立意对象、5种写作态度 经过审题立意后&#xff0c;我们要根据我们的立意&#xff0c;确定一个主题&#xff0c;这个主题必须通过文章的标题直接表达出来。 标题的基本要求 主题清晰&#xff0c;态度明确 第一&#xff0c;阅卷人看到一篇论说文的标…

【动态规划part13】| 300.最长递增子序列、674.最长连续递增序列、718.最长重复数组

目录 &#x1f388;LeetCode 300.最长递增子序列 &#x1f388;LeetCode 674. 最长连续递增序列 &#x1f388;LeetCode 718. 最长重复子数组 &#x1f388;LeetCode 300.最长递增子序列 链接&#xff1a;300.最长递增子序列 给你一个整数数组 nums &#xff0c;找到其…

camund——2、cancelActivityInstance()与多实例下getActiveActivityIds()获取不到当前任务的节点。

在多实例&#xff08;会签或者并行网关&#xff09;时如果使用以下代码来进行驳回时&#xff0c;使用 **List activeActivityIds runtimeService.getActiveActivityIds(instanceId);**来获取当前活动的节点会出现获取不到情况。 runtimeService.createProcessInstanceModific…

基于Linux操作系统中的MySQL用户权限管理(三十二)

用户权限管理 目录 一、概述 二、用户权限类型 1、ALL PRIVILEGES 2、CREATE 3、DROP 4、SELECT 5、INSERT 6、UPDATE 7、DELETE 8、INDEX 9、ALTER 10、CREATE VIEW和CREATE ROUTINE 11、SHUTDOWN 12、GRANT OPTION 三、用户赋权 四、权限删除 五、用户删除 …

RTThread实际开发问题统计

文章目录 开启DMA rx中断&#xff0c;数据帧总是接收不全就产生中断&#xff1f;PB3/PB4等和JTAG复用的管脚不能使用&#xff1f;uart使用DMA传输&#xff0c;调用close再open之后就接收不到数据了&#xff1f; 开启DMA rx中断&#xff0c;数据帧总是接收不全就产生中断&#x…

C语言指针应该这么学?

数组名的意义&#xff1a; 1. sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小。 2. &数组名&#xff0c;这里的数组名表示整个数组&#xff0c;取出的是整个数组的地址。 3. 除此之外所有的数组名都表示首元素的地址。 根据以上数…

[CrackMe]Cruehead.1.exe的逆向及注册机编写

1. 逆向分析过程 作者弄了很多个对话框来迷惑破解者, 然后真正有用的对话框只有这个 这个窗口过程函数处理的是父窗口 其他的不关心, 只关心WM_COMMAND消息 里面有3个分支, 其中最重要的是按下register按钮的那个 整个逻辑非常清晰, 其算法是把name的每个字符转成大写字母…

测试测试用例设计常见面试题

测试|测试用例设计常见面试题 文章目录 测试|测试用例设计常见面试题1.怎么模拟弱网&#xff08;测试技巧&#xff09;2.怎么测试接口&#xff08;测试技巧&#xff09;3.怎么对冒泡排序测试&#xff08;代码类&#xff09;4.怎么对linux的zip命令进行测试&#xff08;软件类&a…

Spring Boot项目的创建

hi 大家好,又见面了,今天继续讲解Spring Boot 文章目录 &#x1f436;1.什么是Spring Boot?&#x1f436;2.Spring Boot的优势&#x1f436;3.Spring Boot项目创建&#x1f33c;3.1使用ieda创建&#x1f95d;3.1.1下载插件Spring Boot Helper&#x1f95d;3.1.2创建项目 &…

基于ThreadPoolExecutor实现动态线程池

项目上&#xff0c;我们是根据业务的使用频率&#xff0c;基于ThreadPoolExecutor自定义一个线程池&#xff0c;线程池的核心线程数、最大线程数、阻塞队列的容量都是估计的设置的&#xff0c;但是不知道线程资源的真正使用情况。 1.ThreadPoolExecutor配置参数动态修改 先来…

Linux Day04

目录 一、文件压缩与解压命令 1.1 tar cvf 文件名 ---打包命令生成.tar 1.2 tar xvf 文件名 ----解开包 生成文件 1.3 gzip .tar 压缩 生成.tar.gz压缩包 1.4 gzip -d .tar.gz 解压成包 1.5 直接把压缩包解压成文件 tar zxf .tar.gz 二、Linux 系统上 C 程序的…

Python实现自动登录和下单脚本,代码嘚魅力~

目录标题 前言环境使用:代码实现思路配置浏览器驱动代码实现尾语 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 学python对selenium应该不陌生吧 Selenium 是最广泛使用的开源 Web UI&#xff08;用户界面&#xff09;自动化测试套件之一。 Selenium 支持的语言包括C#…

Winget简单介绍

为什么明明Windows的UI更为便捷&#xff0c;但是还是那么多人用的linux&#xff0c;或者mac 主要还是linux和mac的命令行更好用。 虽然windows中也出现了choco这种东西&#xff0c;但是非官方的总觉得不是很令人信服。 这边挂一下官方文档&#xff0c;然后在开始自己的简单实…

深入理解Vue响应式系统:数据绑定探索

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

某某大学某学院后台Phar反序列化GetShell

觉得这个洞还算有点意思&#xff0c;可以记录一下 首先在另一个二级学院进行目录扫描时发现源码www.rar&#xff0c;并且通过一些页面测试推测这两个二级学院应该是使用了同一套CMS 分析源码&#xff0c;发现使用的是ThinkPHP 5.1.34 LTS框架 通过APP、Public得到后台访问路径…

开放自动化软件的硬件平台

自动化行业的产品主要以嵌入式系统为主&#xff0c;历来对产品硬件的可靠性和性能都提出很高的要求。最典型的产品要数PLC。PLC 要求满足体积小&#xff0c;实时性&#xff0c;可靠性&#xff0c;可扩展性强&#xff0c;环境要求高等特点。它们通常采用工业级高性能嵌入式SoC 实…

无涯教程-jQuery - Selectable选择函数

选择能力功能可与JqueryUI中的交互一起使用。此功能可在任何DOM元素上启用选择能力功能。用光标绘制一个框以选择项目。按住Ctrl键可进行多个不相邻的选择。 Select able - 语法 $( "#selectable" ).selectable(); Select able - 示例 以下是一个简单的示例&…

反弹shell确认是否是docker容器

反弹shell确认是否是docker容器 方法一 如果根目录中存在.dockerwenv文件&#xff0c;证明是doker容器 ls /.dockerenv方法二 出现以下类似内容&#xff0c;证明是在doker容器内 cat /proc/1/cgroup