Laravel怎么配合Workerman命令行监听MQTT

 3061

Laravel+Workerman怎么监听MQTT?下面本篇文章给大家介绍一下Laravel配合Workerman命令行监听MQTT的方法,希望对大家有所帮助。


Laravel怎么配合Workerman命令行监听MQTT


公司是做物联网的,经常有服务端通过PHP与物联网设备通过MQTT协议通信,恰好PHP框架用的是Laravel,刚接触的时候发现没什么比较接近的资料,自己摸索了一阵,已经在几个项目使用上了,这里将相关的步骤贴出来,方便以后自己查阅以及有类似需求的朋友参考。

写在开始

众所周知,PHP是一门专为Web设计的语言,绝大部分时间都是与Web Server通信,再后端一点,也是与别的后端语言配合做“前端”,其底层设计也限制了其本身更适合做Web那些事,所以如果想要用来服务端监听MQTT,就需要别的库来配合,这里说的库主要就两个,分别是workerman及swoole,当前(2019.08)就服务端监听MQTT实际使用体验来说,分别如下:

workerman:

安装简单,一行composer命令就能安装好 

MQTT库使用的人多,更新日期更近

支持MQTT TLS/SSL加密

文档详细

swoole:

安装相比workerman复杂,每个运行环境都要单独安装,可能需要编译环境。

MQTT使用的人较少,更新时间比较久远

文档少,能查找到的资料也少

不支持TLS/SSL加密,如果需要加密的环境可能不是很友好

综上所述,我最终选择了workerman,本文以workerman作为MQTT库进行配置使用。


安装Laravel,已安装可省略

现代PHP开发composer应该是必不可少的了,基本上大点的框架都会推荐使用composer,所以这里以composer来安装Laravel,命令如下:

  1. composer create-project --prefer-dist laravel/laravel workerman-mqtt '5.5.*'

Laravel指定版本为5.5.x,这是目前(2019.08)的唯一LTS版本,考虑到企业项目的稳定及安全,还是选择LTS。项目名称为workerman-mqtt,专门用这个来测试MQTT。

如果composer太慢,可以考虑使用阿里云等国内composer源加快安装速度。


安装workerman-mqtt

上面说了,用composer安装workerman-mqtt很简单,只需要一行命令:

  1. ➜  cd workerman-mqtt
  2. ➜  composer require workerman/mqtt
  3. Using version ^1.0 for workerman/mqtt
  4. ./composer.json has been updated
  5. Loading composer repositories with package information
  6. Updating dependencies (including require-dev)
  7. Package operations: 2 installs, 0 updates, 0 removals
  8.   - Installing workerman/workerman (v3.5.20): Loading from cache
  9.   - Installing workerman/mqtt (v1.0): Loading from cache
  10. workerman/workerman suggests installing ext-event (For better performance. )
  11. Package phpunit/phpunit-mock-objects is abandoned, you should avoid using it. No replacement was suggested.
  12. Writing lock file
  13. Generating optimized autoload files
  14. Carbon 1 is deprecated, see how to migrate to Carbon 2.
  15. https://carbon.nesbot.com/docs/#api-carbon-2
  16.     You can run './vendor/bin/upgrade-carbon' to get help in updating carbon and other frameworks and libraries that depend on it.
  17. > Illuminate\Foundation\ComposerScripts::postAutoloadDump
  18. > @php artisan package:discover
  19. Discovered Package: fideloper/proxy
  20. Discovered Package: laravel/tinker
  21. Discovered Package: nesbot/carbon
  22. Package manifest generated successfully.


新建artisan命令

既然是使用Laravel配合workerman监听MQTT,那artisan自然是不二的选择了,能使用Laravel的组件,还能使用artisan命令管理监听进程。创建相关命令文件:

  1. ➜  php artisan make:command mqtt
  2. Console command created successfully.

然后编辑生成的workerman-mqtt/app/Console/Commands/mqtt.php文件,将文件改成如下内容:

  1. <?php
  2.  
  3. namespace App\Console\Commands;
  4.  
  5. use Illuminate\Console\Command;
  6. use Workerman\Worker;
  7.  
  8. class mqtt extends Command
  9. {
  10.     protected $signature = 'mqtt {action}';
  11.  
  12.     protected $description = 'PHP Server MQTT Client';
  13.  
  14.     protected $client_id = 'php-server';
  15.  
  16.     public function __construct()
  17.     {
  18.         parent::__construct();
  19.     }
  20.  
  21.     public function handle()
  22.     {
  23.         global $argv;
  24.         $arg = $this->argument('action');
  25.         $argv [1] = $arg;
  26.  
  27.         $worker = new Worker();
  28.         $worker->count = 1;
  29.         $worker->onWorkerStart = function () {
  30.             $mqtt = new \Workerman\Mqtt\Client("mqtt://" . env('MQTT_HOST') . ":" . env('MQTT_PORT'), array(
  31. //                'ssl' => array(
  32. //                    'local_cert' => base_path() . '/path/mqtt/client.crt',
  33. //                    'local_pk' => base_path() . '/path/mqtt/client.key',
  34. //                    'cafile' => base_path() . '/path/mqtt/ca.crt',
  35. //                    'verify_peer' => false,
  36. //                    'allow_self_signed' => true,
  37. //                ),
  38. //                $mqtt->transport = 'ssl';
  39.                 'username' => env('MQTT_USER'),
  40.                 'password' => env('MQTT_PASSWORD'),
  41.                 'debug' => env('MQTT_DEBUG'),
  42.                 'client_id' => $this->client_id . mt_rand(0, 999),
  43.                 'will' => [
  44.                     'topic' => 'status/' . $this->client_id,
  45.                     'content' => 0,
  46.                     'qos' => 2,
  47.                     'retain' => true,
  48.                 ]
  49.             ));
  50.             $mqtt->onConnect = function ($mqtt) {
  51.                 $mqtt->subscribe('/iot/#');
  52.             };
  53.             $mqtt->onMessage = function ($topic, $data, $mqtt) {
  54.                                 var_dump($topic);
  55.                                 var_dump($data);
  56.                                 //TODO 业务代码
  57.  
  58.                                 //publish消息到topic
  59.                                 $mqtt->publish('test', 'hello workerman mqtt');
  60.             };
  61.             $mqtt->connect();
  62.         };
  63.         Worker::runAll();
  64.     }
  65. }

然后到项目根目录下面的.env文件添加下面几项:

  1. MQTT_HOST=mqtt-broker.test
  2. MQTT_PORT=1883
  3. MQTT_USER=username
  4. MQTT_PASSWORD=password
  5. MQTT_DEBUG=true

其中,onConnect里面的subscribe后面是需要监听的topic,当收到新消息的时候,onMessage里面的topic是消息的topic,data就是具体的消息信息了,有了这两个,我们可以在onMessage里面写我们的业务逻辑,当然也可以引入Laravel框架本身的一些组件,比如数据库、日志等,也可以与别的服务比如说Redis、消息队列MQ等配合进行缓存或者使用消息队列等。


执行mqtt命令

和别的artisan命令差不多,直接命令行运行就好了:

  1. ➜  php artisan mqtt start
  2. Workerman[artisan] start in DEBUG mode
  3. ------------------------------------- WORKERMAN --------------------------------------
  4. Workerman version:3.5.20          PHP version:7.1.30
  5. -------------------------------------- WORKERS ---------------------------------------
  6. proto   user            worker          listen          processes    status
  7. tcp     zoco            none            none            1             [OK]
  8. --------------------------------------------------------------------------------------
  9. Press Ctrl+C to stop. Start success.
  10. -> Try to connect to mqtt://mqtt-broker.test:1883
  11. -- Tcp connection established
  12. -> Send CONNECT package client_id:php-server-superuser-subscribe95 username:username password:password clean_session:1 protocol_name:MQTT protocol_level:4
  13. <- Recv CONNACK package, MQTT connect success
  14. -> Send SUBSCRIBE package, topic:/iot/# message_id:1
  15. <- Recv SUBACK package, message_id:1

注意别忘了后面的start,这是workerman本身需要的启动参数。

因为workerman设定是常驻内存,正常情况下是在持续在监听的,即使程序有bug被终止,workerman也会自动新建一个进程进行处理。

如果生产环境需要长期监听处理MQTT数据,建议使用systemctl等命令来管理。


不足之处

虽然到上面为止已经可以作为客户端在服务端监听MQTT的消息,但是这里有个不足之处就是,我到目前没找到办法单独调用这个库在处理实际业务逻辑的时候publish消息到指定的topic。

还有一点是,使用这个库,不能同时运行两个使用了这个库的artisan命令,会有如下提示:

  1. ➜  php artisan mqtt start
  2. Workerman[artisan] start in DEBUG mode
  3. Workerman[artisan] already running

这个问题搜遍了全网也没发现有解决的办法。虽然可以通过Timer类添加定时功能通过另类办法解决,但是在需要效率的情况下,这并不是最优解,如果有别的方案,建议还是不要选择PHP作为服务端来处理MQTT相关业务。

本文网址:https://www.zztuku.com/index.php/detail-13568.html
站长图库 - Laravel怎么配合Workerman命令行监听MQTT
申明:本文转载于《CSDN》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐

    ThinkPHP5验证码图片如何生成