Laravel5.3和Workerman結合使用(異步)

下面由workerman使用教程欄目給大家介紹laravel5.3和workerman結合使用(異步)的方法,希望對需要的朋友有所幫助!

Laravel5.3和Workerman結合使用(異步)

網上查閱資料有現成和workerman結合的composer組件,但個人感覺不太靠譜,github上star太少,而且怕有問題也不好調,就想自己先試試。

我的辦法因為修改要一點Workerman源碼,且是直接引入Workerman的代碼文件,感覺有點low,但才智有限,暫時沒想到更好的方法。

準備:

1.需先了解laravel框架下命令行的使用,參考中文版教程

2.需了解Workerman的基本知識

場景:用戶注冊后,異步方式給用戶發送郵件提醒

1.把Workerman框架放到app目錄下

2.創建命令代碼:

php?artisan?make:command?SendEmail
namespace?AppConsoleCommands;  use?IlluminateConsoleCommand; use?IlluminateSupportFacadesLog; use?IlluminateSupportFacadesMail; use?IlluminateMailMessage; use?WorkermanWorker;  require?app_path('Workerman/Workerman_Linux/Autoloader.php');  class?SendEmail?extends?Command { ????/** ?????*?The?name?and?signature?of?the?console?command. ?????* ?????*?@var?string ?????*/ ????protected?$signature?=?'send:email?{action}';  ????/** ?????*?The?console?command?description. ?????* ?????*?@var?string ?????*/ ????protected?$description?=?'Command?description';  ????/** ?????*?Create?a?new?command?instance. ?????* ?????*?@return?void ?????*/ ????public?function?__construct() ????{ ????????parent::__construct(); ????}  ????/** ?????*?Execute?the?console?command. ?????* ?????*/ ????public?function?handle() ????{ ????????$mailWorker?=?new?Worker('Text://0.0.0.0:12345'); ????????$mailWorker->count?=?4; ????????$mailWorker->name?=?'MailWorker'; ????????$mailWorker->onMessage?=?function?($connection,?$emailData)?{ ????????????$emailData?=?json_decode($emailData); ????????????$name?=?$emailData->name; ????????????$email?=?$emailData->to; ????????????Mail::raw('注冊成功',?function?(Message?$message)?use?($email)?{ ????????????????$message->to($email)->subject(trans('mail.welcome_register')); ????????????});  ????????????//?寫入日志 ????????????Log::useFiles(storage_path()?.?'/logs/event.log',?'info'); ????????????Log::info("{$name}({$email})注冊成功"); ????????};  ????????Worker::runAll(); ????} }

以上是workerman服務端,用命令行啟動:

php?artisan?send:email?start

此時命令行下會報錯:Workerman[artisan] not run,原因是Workerman會把第一個參數artisan當前啟動文件,而實際上,send:email才是我們想要的啟動文件

解決:修改Workerman的解析參數代碼

WorkermanWorkerman_LinuxWorker.php,修改parseCommand方法(只要把$argv的鍵都加1就行):

/** ?????*?Parse?command. ?????*?php?yourfile.php?start?|?stop?|?restart?|?reload?|?status ?????* ?????*?@return?void ?????*/ ????protected?static?function?parseCommand() ????{ ????????global?$argv;  ????????if($argv[0]?==?'artisan')?//?laravel框架下處理 ????????{ ????????????//?Check?argv; ????????????$start_file?=?$argv[1];  ????????????if?(!isset($argv[2]))?{ ????????????????exit("Usage:?php?yourfile.php?{start|stop|restart|reload|status}n"); ????????????}  ????????????//?Get?command. ????????????$command??=?trim($argv[2]); ????????????$command2?=?isset($argv[3])???$argv[3]?:?''; ????????} ????????else ????????{ ????????????//?Check?argv; ????????????$start_file?=?$argv[0]; ????????????if?(!isset($argv[1]))?{ ????????????????exit("Usage:?php?yourfile.php?{start|stop|restart|reload|status}n"); ????????????}  ????????????//?Get?command. ????????????$command?=?trim($argv[1]); ????????????$command2?=?isset($argv[2])???$argv[2]?:?''; ????????} ???? ?????//?只要略修改上面的參數解析部分即可? ?????.......................... }

重新啟動OK:

php?artisan?send:email?start

3.服務端完成了,下面是客戶端代碼

我的郵件操作代碼是當作事件邏輯,所以在事件監聽器文件寫代碼:

appListenersSendMailEventListener.php:
<?php namespace AppListeners;  use AppEventsSendMailEvent;class SendMailEventListener extends BaseEventListener {     /**      * Create the event listener.      *      * @return void      */     public function __construct()     {         //     }      /**      * Handle the event.      *      * @param  SendMailEvent $event      * @return void      */     public function handle($event)     {         // 發送郵件通知注冊成功         if ($event->user-&gt;scene?==?'do_register')?{ ????????????$email?=?$event-&gt;user-&gt;email;  ????????????//$ip?=?"mail_worker?的ip"?,本機的話為127.0.0.1 ????????????$socket?=?@stream_socket_client('tcp://127.0.0.1:12345',?$errno,?$errmsg,?5); ????????????if?($socket)?{ ????????????????$mail_data?=?['name'=&gt;$event-&gt;user-&gt;name,'to'?=&gt;?$email,?'content'?=&gt;?trans('mail.welcome_register')]; ????????????????//?注意,Text協議后面"n"換行符是必須的 ????????????????$mail_buffer?=?json_encode($mail_data)?.?"n"; ????????????????//?發送給mail?worker ????????????????fwrite($socket,?$mail_buffer); ????????????}  //????????????$email?=?$event-&gt;user-&gt;email; //????????????Mail::raw('注冊成功',function?(Message?$message)?use?($email)?{ //????????????????$message-&gt;to($email)-&gt;subject(trans('mail.welcome_register')); //????????????}); ????????} ????} }

4.總結步驟

啟動服務端—注冊用戶—觸發SendEmail事件—socket客戶端往服務端寫數據—服務端發送郵件

推薦:workerman使用教程

? 版權聲明
THE END
喜歡就支持一下吧
點贊11 分享