前文已经在啊里云宝塔中搭建好mqtt服务器,这里就在tp5及小程序中实现订阅及发布

一、tp5实现

1、先上网下载phpMQTT.php文件
https://github.com/bluerhinos/phpMQTT/blob/master/phpMQTT.php 网上下载的文件放入tp5文件后,有很多:void红色错误,可能和我的phpstorm有冲突,手动把所有红色提示错误修改

2、在tp目录extend中,创建文件夹phpmqtt,把上下好的phpMQTT.php文件放到这里,phpMQTT.php文件中修改 namespace phpmqtt

3、在admin/controller中创建自定义php文件,这里测试创建index,代码如下

//mqtt发布
    public function pub(){
        // 客户端id  可以用随机数
        $client = "tp5Mqtt";
        // mqtt主机 主机,请配置为自己的主机
        $host = "120.xx.xx.xx";
        // mqtt端口
        $port = 1883;
        // 密钥 用于证书配置,如果需要ssl认证,则必须填写
//        $this->cert= 'ca.pem';
        // mqtt账号
        $username = "test";
        // mqtt密码
        $password = "123";
        // 订阅主题 订阅的主题,注意使用的主题一定要是mqtt配置过的主题,比如百度天工需要策略认证过的
        // 自己学习的时候,可以随意自定义,一般跟发布主题一致便可以收到消息
        // 如要要接受所有主题,请使用#
        $topics_name = "hometopic";

        //引入phpMQTT 创建mqtt实例
        Loader::import('phpmqtt/phpMQTT', EXTEND_PATH);
        $mqtt = new \phpmqtt\phpMQTT($host,$port,$client);

        //发布,发布内容可自定义,这里写死
        if ($mqtt->connect(true, NULL, $username, $password)) {
            $mqtt->publish($topics_name, 'Hello World! at ' . date('r'), 1, false);
            $mqtt->close();
        } else {
            echo "Time out!\n";
        }
    }


    /**
     * 订阅
     * 要使用命令行运行此方法!!!
     *  think5.0 运行方法为 在宝塔终端中,cd到Public 目录  然后用守户程序运行 nohup php index.php admin/index/sub &
     * 该类主要为订阅,建议订阅代码和发布代码不要写在同一个类中,避免修改造成不必要的误改。
     * 每次更新该类后需要重启mqtt订阅,否则新的改动不会生效。
     * 请在相应的位置放入phpMQTT的库
     * 库代码:https://github.com/bluerhinos/phpMQTT/blob/master/phpMQTT.php
     * 类库使用的时候注意命名空间,类名称命名要和thinkphp的保持一致,不然会报错
     */
    public function sub(){
        // 客户端id  可以用随机数
        $client = "tp5Mqtt";
        // mqtt主机 主机,请配置为自己的主机
        $host = "120.xx.xx.xx";
        // mqtt端口
        $port = 1883;
        // 密钥 用于证书配置,如果需要ssl认证,则必须填写,正式上线前再修改
//        $this->cert= 'ca.pem';
        // mqtt账号
        $username = "test";
        // mqtt密码
        $password = "123";
        // 订阅主题 订阅的主题,注意使用的主题一定要是mqtt配置过的主题,比如百度天工需要策略认证过的
        // 自己学习的时候,可以随意自定义,一般跟发布主题一致便可以收到消息
        // 如要要接受所有主题,请使用#
        $topics_name = "hometopic";

        //引入phpMQTT 创建mqtt实例
        Loader::import('phpmqtt/phpMQTT', EXTEND_PATH);
        $mqtt = new \phpmqtt\phpMQTT($host,$port,$client);

        if(!$mqtt->connect(true, NULL, $username, $password)) {
            exit('error');   //连接失败
        } else {
            echo "success"; //连接成功
        }
        //topics["topic"]  为接受的主题名  需要和发送的主题名一致  否则会订阅不到
        //订阅信息 Qos为信息登记,需要和发送的等级一致
        $topics[$topics_name] = array("qos" => 1, "function" =>array($this,"onMessage"));

        $mqtt->subscribe($topics, 0);

        //死循环监听
        while($mqtt->proc()){

        }
        $mqtt->close();
    }
    /**
     * 在此处接MQtt的信息 进行业务处理
     * @param $topic
     * @param $msg
     */
    function onMessage($topic,$msg){
        echo "---onMessage---";
        $data['topicName'] = $topic;
        $data['content'] = $msg;
        //保存数据到数据库
        LyTestModel::create($data);
    }

4、根据上面订阅代码,在宝塔中运行守护进行,可以实现订阅进保存数据到数据库
在宝塔终端中,cd到Public 目录 然后用守户程序运行 nohup php index.php admin/index/sub &
守护进程运行后,可以关必终端,会在后台运行(PS:在实战中,遇到命令端的php版本和后台的php版本不同,导致启动不了,可以在宝塔的网站,php命令行版本修改为同一版本,还要验证后台的启动是不是通过index.php)

5、在linux上查看进程ps aux

6、在linux上结束进程  
kill PID         可以结束指定PID进程
pkill -9 php index.php admin/index/sub        结束所有同名称进程



二、微信小程序实现

1、上网下载mqqt.min.js,放入utils中

2、js代码,内部测试体验服成功,正式上线,应该要把host切换为wss

// pages/test/test.js
//获取应用实例
const app = getApp();
var mqtt = require('../../utils/mqtt.min.js')
var client = null
Page({

  /**
   * 页面的初始数据
   */
  data: {
    host: 'wx://120.xx.xx.xxx/mqtt',
    topic: 'homeTopic',
    username: 'test',
    password: '123',
    msg:{
      "msgType": 500,
      "queryType": 0,
      "devId": "d000001",
      "txnNo": 1234567890123
    },

  },
  connectMqtt:function(){
    var that = this
    console.log('connectMqtt')
    const options = {
      conectTimeout:4000,
      clientId: 'wx_' + parseInt(Math.random() * 100 + 800, 10),
      port:8083,
      username: that.data.username,
      password: that.data.password,
    }
    client = mqtt.connect(that.data.host,options)
    client.on('connect',(e) =>{
      console.log('服务器连接成功')
      client.subscribe(that.data.topic, {
        qos: 1
      }, function (err) {
        if (!err) {
          console.log('订阅成功')
        }
      })
    })
    client.on('message',function(topic,message){
      console.log('收到'+message.toString())
    })
    client.on('reconnect', (error)=> {
      console.log('正在重连:' , error)
    })
    client.on('error', (error) => {
      console.log('连接失败', error)
    })
  },
  open:function(){
    console.log('open')
    client.publish(this.data.topic, 'on')
  },
  close: function () {
    console.log('close')
    client.publish(this.data.topic, 'off')
  },
  

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.connectMqtt()
  },

 
})

注意:各种通信要联接好,注意topic主题名称,需要一致才能订阅,mqtt的qos,0,1,2分别代表什么,可以百度一下