下面由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->scene?==?'do_register')?{ ????????????$email?=?$event->user->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'=>$event->user->name,'to'?=>?$email,?'content'?=>?trans('mail.welcome_register')]; ????????????????//?注意,Text協議后面"n"換行符是必須的 ????????????????$mail_buffer?=?json_encode($mail_data)?.?"n"; ????????????????//?發送給mail?worker ????????????????fwrite($socket,?$mail_buffer); ????????????} //????????????$email?=?$event->user->email; //????????????Mail::raw('注冊成功',function?(Message?$message)?use?($email)?{ //????????????????$message->to($email)->subject(trans('mail.welcome_register')); //????????????}); ????????} ????} }
4.總結步驟
啟動服務端—注冊用戶—觸發SendEmail事件—socket客戶端往服務端寫數據—服務端發送郵件
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END