根据观法提供的workerman官方客户端在webman中执行命令:composer require workerman/mqtt
然后执行执行客户端接收mqtt消息是可以的,
但是后面开始编写业务的时候,如下面代码:
Log::info($topic);
Log::info($content);
就会报错:
TypeError: Argument 1 passed to support\Log::handlers() must be of the type array, null given, called in D:\develop\php\webman_admin\vendor\workerman\webman-framework\src\support\Log.php
on line 55 and defined in D:\develop\php\webman_admin\vendor\workerman\webman-framework\src\support\Log.php:67
下面是完整代码:
启动代码:
declare(strict_types=1);
use Workerman\Worker;
use \app\mqttService\MqttService;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker();
$worker->onWorkerStart = function(){
$options = [
'username' => 'admin',
'password' => '123456',
];
$mqtt = new Workerman\Mqtt\Client('mqtt://192.168.1.5:1883',$options);
$mqtt->onConnect = function($mqtt) {
$mqtt->subscribe('mqtt/face/1400754/Snap');
};
$mqttService = new MqttService();
$mqtt->onMessage = function($topic, $content) use ($mqttService){
$mqttService->handlerMessage($topic,$content);
//var_dump($topic, $content);
};
$mqtt->connect();
};
Worker::runAll();
业务代码, $mqttService->handlerMessage里的逻辑:
public function handlerMessage($topic,$content) {
if (!empty($topic)) {
//echo "topic:".$topic.'\r\n';
Log::info($topic);
Log::info($content);
}
}
完整异常trace:
TypeError: Argument 1 passed to support\Log::handlers() must be of the type array, null given, called in D:\develop\php\webman_admin\vendor\workerman\webman-framework\src\support\Log.php
on line 55 and defined in D:\develop\php\webman_admin\vendor\workerman\webman-framework\src\support\Log.php:67
Stack trace:
#0 D:\develop\php\webman_admin\vendor\workerman\webman-framework\src\support\Log.php(55): support\Log::handlers(NULL)
#1 D:\develop\php\webman_admin\vendor\workerman\webman-framework\src\support\Log.php(139): support\Log::channel()
#2 D:\develop\php\webman_admin\app\mqttService\MqttService.php(26): support\Log::__callStatic('info', Array)
#3 D:\develop\php\webman_admin\mqtt_subscribe.php(21): app\mqttService\MqttService->handlerMessage('mqtt/face/basic', '{\r\n"operator": ...')
#4 [internal function]: {closure}('mqtt/face/basic', '{\r\n"operator": ...', Object(Workerman\Mqtt\Client))
#5 D:\develop\php\webman_admin\vendor\workerman\mqtt\src\Client.php(599): call_user_func(Object(Closure), 'mqtt/face/basic', '{\r\n"operator": ...', Object(Workerman\Mqtt\Client))
#6 D:\develop\php\webman_admin\vendor\workerman\workerman\Connection\TcpConnection.php(646): Workerman\Mqtt\Client->onConnectionMessage(Object(Workerman\Connection\AsyncTcpConnection), A
rray)
#7 D:\develop\php\webman_admin\vendor\workerman\workerman\Events\Select.php(311): Workerman\Connection\TcpConnection->baseRead(Resource id #42)
#8 D:\develop\php\webman_admin\vendor\workerman\workerman\Worker.php(1479): Workerman\Events\Select->loop()
#9 D:\develop\php\webman_admin\vendor\workerman\workerman\Worker.php(1399): Workerman\Worker::forkWorkersForWindows()
#10 D:\develop\php\webman_admin\vendor\workerman\workerman\Worker.php(560): Workerman\Worker::forkWorkers()
#11 D:\develop\php\webman_admin\mqtt_subscribe.php(27): Workerman\Worker::runAll()
#12 {main}
我的目的就是想用workerman/mqtt消费消息,然后使用webman的数据库,redis等组件写业务
webman启动时会读取配置初始化webman运行环境,初始化support\Log。但是你的mqtt_subscribe.php是一个单独脚本,不是webman的一部分,缺少这些初始化,所以无法使用support\Log。
你可以参考webman自定义进程部分,将你的mqtt业务放到webman自定义进程中运行,这样就能用webman的运行环境了。
已经成功了,但是有个问题,就是会报一个错: Uncaught Exception: class \Protocols\Mqtt not exist,我看了也确实没有这个类:我直接在onWorkerStart初始化,但是就不会onConnect和onMessage了,很尴尬,还是需要写进协议里:
你看下是不是用错客户端了,用Workerman\Mqtt\Client。
MqttClient作为服务端有监听端口时,有客户端连接监听的端口请求时才会触发MqttClient的onConnect和onMessage,否则不会触发。
用上了,现在连上了,不过有个问题,就是不会触发onConnet,onMessage
之前单独使用Workerman\Mqtt\Client这个组件是可以接收连接和消息的
服务器也接收到消息请求消息了
就是后续消息没有接收到,很奇怪
紧接着webman 客户端就报错:Mqtt client: No connection to broker
大佬们,是不是我的姿势不对?感觉要不自己用workerman/mqtt组件+mysql组件+redis组件自己搭一个简易的小项目
类似设置
$mqtt->onConnect = function(){};
,$mqtt客户端不会出发你的public onConnect(){}
,因为public onConnect(){}
是作为服务端才能触发的。onMessage也一样,别搞混了好的,感觉大佬,已经可以了
大佬们说的我都看不懂