PHP Laravel中如何获取并返回MQTT回调函数的结果给前端
核心问题说明
你现在的代码有两个核心问题没法直接返回数据给前端:
- MQTT的
subscribe方法只是注册了订阅回调,没有执行消息循环,根本收不到消息 - HTTP请求是短生命周期的,默认MQTT消息循环是阻塞常驻的,会导致请求超时,不可能一直挂着等消息
方案1:适配AJAX轮询场景
如果你接受前端每隔几秒轮询一次接口拿最新数据,直接修改控制器代码如下:
public function KreirajMqtt() { $server = 'mqtt3.thingspeak.com'; $port = 1883; $username = 'myUsername'; $clientId = 'myId'; $password = 'myPassword'; // 定义变量存储收到的消息 $receivedData = null; $mqtt = new MqttClient($server, $port, $clientId); $connectionSettings = new ConnectionSettings(); $connectionSettings ->setUsername($username) ->setPassword($password) ->setKeepAliveInterval(15) ->setLastWillTopic('channels/myChannel/subscribe') ->setLastWillMessage('client disconnect') ->setLastWillQualityOfService(0); $mqtt->connect($connectionSettings, true); $mqtt->subscribe( 'channels/myChannel/subscribe', function ($topic, $message) use (&$receivedData, $mqtt) { // 格式化收到的消息 $receivedData = [ 'topic' => $topic, 'content' => json_decode($message, true) ?: $message ]; // 收到消息后立刻中断消息循环 $mqtt->interrupt(); }, 0 ); // 运行消息循环,最多等待2秒,超时自动退出 $mqtt->loop(true, 2); // 主动断开MQTT连接 $mqtt->disconnect(); // 以JSON格式返回数据给前端axios return response()->json([ 'success' => !empty($receivedData), 'data' => $receivedData ]); }
前端调用示例(Vue+Axios)
// 可以写在定时轮询里,也可以写在mounted钩子中 async function fetchMqttData() { const res = await axios.get('/你的控制器路由地址') if (res.data.success) { // 把数据赋值给Vue的响应式变量,直接渲染到页面 this.mqttData = res.data.data } }
方案2:实时推送场景(低延迟推荐)
如果需要MQTT一收到新消息就立刻推给前端,不要用HTTP短连接接口实现,按下面步骤改:
- 后端额外写一个CLI命令常驻进程,专门用来订阅MQTT主题
- 后端集成WebSocket服务,CLI进程收到MQTT消息后,通过WebSocket推送给前端
- 前端Vue直接连接WebSocket,监听消息事件,收到后实时更新页面
这种方案没有轮询延迟,性能更高,是实时数据展示的标准实现方式。
内容的提问来源于stack exchange,提问作者Raskoljnikovic
相关产品推荐
相关产品推荐

