无法使用 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">×</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">×</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 客户端上的客户端订阅页面中实际的消息。
我下载了 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">×</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">×</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 客户端上的客户端订阅页面中实际的消息。