无法使用 PhpMqtt-Client 从 mqtt 代理接收消息

Unable to receive messages from mqtt broker using PhpMqtt-Client

我下载了 mosquitto mqtt broker 并 运行 在本地机器上的端口 1883 上的代理,并使用提供的 mosquitto_pub.exe 和 mosquitto_sub.exe 文件成功测试了它的工作。当我发布关于某个主题的消息时,我可以从订阅者那里收到它。我使用 windows 10 中提供的 cmd 工具对其进行了测试(对于同一台机器上的发布者和订阅者)。现在我对客户端的理解是,经纪人需要 运行 才能订阅它。因此,根据我的要求,我下载了 https://github.com/php-mqtt/client 并在我的 php 文件中使用了 ajax 我试图从发布者那里获取发布的消息,这是一个先前启动的 cmd 工具。但是我无法收到任何消息,在等待超时时间后我收到错误消息(500-内部服务器错误),但是在订阅者 cmd window 中我收到了消息。请帮助我了解我的方法有什么问题。我用它来获取发布到上述主题的所有设备。我还将预期的输出作为由给定代码生成的图像给出。 “批准”按钮当然不在给定的代码中。一旦我在左侧列表中获得发布者列表,我就会添加它。那里列出的传感器只是硬编码 html - 以下是我的代码 -

php代码-

<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
  <!-- Content Header (Page header) -->
  <section class="content-header">
    <h1>
      Manage
      <small>Devices</small>
    </h1>
    <ol class="breadcrumb">
      <li><a href="#"><i class="fa fa-dashboard"></i>Home</a></li>
      <li class="active">Devices</li>
    </ol>
  </section>

  <!-- Main content -->
  <section class="content">
    <!-- Small boxes (Stat box) -->
    <div class="row">
      <div class="col-md-12 col-xs-12">

        <?php    
        ini_set('display_errors', 1); 
        error_reporting(E_ALL);
        if ($this->session->flashdata('success')) : ?>
          <div class="alert alert-success alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <?php echo $this->session->flashdata('success'); ?>
          </div>
        <?php elseif ($this->session->flashdata('error')) : ?>
          <div class="alert alert-error alert-dismissible" role="alert">
            <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
            <?php echo $this->session->flashdata('error'); ?>
          </div>
        <?php endif; ?>

        <div class="box">
          <div class="box-header">
            <h3 class="box-title">Add Device</h3>
          </div>
          <form role="form" action="<?php base_url('devices/create') ?>" method="post">
            <div class="box-body">

              <?php echo validation_errors(); ?>
              <table style="width:max-content;" class="table">
                <tr>
                  <td class="td">
                    <button id="btnscansensors" type="button" class="btn btn-light" style="margin:5px">
                      <img id="wifi" src="../images/icons/wi-fi.png" width="96" /> Scan for sensors
                    </button>
                  </td>
                  <td class="td">
                    <button id="btnstopscansensors" type="button" class="btn btn-light" style="width:96px; height: 110px;margin:5px">
                      <span style="margin-right:5px">Stop Scan</span>
                    </button>
                  </td>
                </tr>
              </table>


              <table class="table">
                <tr>
                  <td class="td">
                    <div class="list-group" style="overflow-y: scroll; height: 25vw;" ;>
                      <?php //sensor list populate on button click 
                      ?>
                      <a href="#" class="list-group-item list-group-item-action">Sensor 1</a>
                      <a href="#" class="list-group-item list-group-item-action">Sensor 2</a>
                      <a href="#" class="list-group-item list-group-item-action">Sensor 3</a>
                      <a href="#" class="list-group-item list-group-item-action">Sensor 4</a>
                      <a href="#" class="list-group-item list-group-item-action">Sensor 5</a>
                    </div>
                  </td>
                  <td class="td">
                  <div class="form-group">
                    <label for="group_name">Device name</label>
                    <input type="text" class="form-control" id="device_name" name="device_name" placeholder="Device name">
                  </div>
                  <div class="form-group">
                    <label for="group_name">Active</label>
                    <select class="form-control" id="status" name="status">
                      <option value="1">Active</option>
                      <option value="2">Inactive</option>
                    </select>
                  </div>
                  </td>
                </tr>
              </table>

            </div>
            <!-- /.box-body -->

            <div class="box-footer">
              <button type="submit" class="btn btn-primary">Save Changes</button>
              <a href="<?php echo base_url('devices/') ?>" class="btn btn-warning">Back</a>
            </div>
          </form>
        </div>
        <!-- /.box -->
      </div>
      <!-- col-md-12 -->
    </div>
    <!-- /.row -->


  </section>
  <!-- /.content -->
</div>
<?php
$dir = dirname(__FILE__, 4);
require $dir.'/vendor/autoload.php';

use PhpMqtt\Client\MqttClient;

if (isset($_POST['function_to_call'])) {
  echo "read_topic being called";
  switch ($_POST['function_to_call']) {

    case 0: {
        echo "read_topic being called";
        read_topic();
        break;
      }

    default:
      break;
  }
}
//function read_topic($topic, $server, $port, $keepalive, $timeout) {
function read_topic()
{
  $server   = 'localhost';
  $port     = 1883;
  $clientId = 'test-subscriber';

  $mqtt = new MqttClient($server, $port, $clientId);

  $mqtt->connect();
  
  $mqtt->subscribe('Registration', function ($topic, $message) {
    echo $message; // for testing 
    echo sprintf("Received message on topic [%s]: %s\n", $topic, $message);
  }, 0);
  $mqtt->loop(true);
  $mqtt->disconnect();
}
?>

<script type="text/javascript">
  $(document).ready(function() {
    $("#devicesSideTree").addClass('active');
    $("#createDevicesSideTree").addClass('active');
    $('#btnstopscansensors').on('click', () => {
      StopScanSensors();
    });
    $("#btnscansensors").on('click', (event) => {
      ScanSensors();
      //$.ajax();
      $.ajax({
        type: 'post',
        //url: 'create.php',
        data: "function_to_call=0",
        success: function(data) {
          alert('successful');
        },
        error: function (request, status, error) {
          alert(request.responseText);
        }
  

      });

      event.preventDefault();
      //$.ajax();
    });

    function ScanSensors() {
      $('#btnscansensors').prop('disabled', true);
      $('#wifi[src$=".png"]').each(function(index, element) {
        element.src = element.src.replace('.png', '.gif');
      });
      //$.ajax();
    }

    function StopScanSensors() {
      $('#btnscansensors').prop('disabled', false);
      $('#wifi[src$=".gif"]').each(function(index, element) {
        element.src = element.src.replace('.gif', '.png');
      });
      //$.ajax();
    }
  });
</script>

PHP 在服务器端运行并呈现 HTML 然后发送到浏览器。当页面在浏览器中加载时,PHP 代码已停止 运行,因此不会收到任何消息。

此外,您的 PHP 代码连接后立即与代理断开连接。

$mqtt->connect();

$mqtt->subscribe('Registration', function ($topic, $message) {
  echo $message; // for testing 
  echo sprintf("Received message on topic [%s]: %s\n", $topic, $message);
}, 0);
$mqtt->loop(true);
$mqtt->disconnect();

如果您想在网页中接收和显示实时 MQTT 消息,则无法使用 PHP,您需要在代理中启用基于 WebSockets 的 MQTT,然后使用 Paho Javascript MQTT.js 客户端上的客户端订阅页面中实际的消息。