本想本身適配的,奈何keng貌似很多,因此果斷選擇官方提供的包來適配233。。。php
默認條件:thinkphp5.1.*版本下,且安裝了swoole擴展git
主要演示:task 任務的投遞github
友情提示:在swoole啓動框架時,需注意靜態變量的使用,會常駐內存(好比單例的變量),... 無圖言卵,我麼的口號是有圖有真相(搞事)
web
如下是swoole下單例模式發送郵件:thinkphp
請看收件人, 圖一給 994xxx@qq.com發送郵件; 圖二給 159xxx@qq.com 發送郵件,其收件人卻有兩(包含圖一中的帳號)。json
composer require topthink/think-swoole=2.0.*
若是你要運行 swoole 的 http 服務器來啓動 thinkPHP框架,執行服務器
php think swoole
默認啓動完成後,會在0.0.0.0:9501啓動一個HTTP Server,能夠直接訪問當前的應用。websocket
swoole的參數能夠在應用配置目錄下的 swoole.php 裏面配置,配置詳情見 thinkPHP官網swoole
擴展中定義了 onWorkerStart
和 onRequest
事件回調方法(若是不熟悉請不要隨意替換),若是你須要自定義swoole
的事件回調方法,能夠在配置文件中使用閉包定義。閉包
如下是個人配置(自定義了task任務回調):
use app\common\lib\utils\Task; use think\facade\Env; use think\facade\Log; // +---------------------------------------------------------------------- // | Swoole設置 php think swoole命令行下有效 // +---------------------------------------------------------------------- return [ // 擴展自身配置 'host' => '0.0.0.0', // 監聽地址 'port' => 9501, // 監聽端口 'mode' => '', // 運行模式 默認爲SWOOLE_PROCESS 'sock_type' => '', // sock type 默認爲SWOOLE_SOCK_TCP 'server_type' => 'http', // 服務類型 支持 http websocket 'app_path' => '', // 應用地址 若是開啓了 'daemonize'=>true 必須設置(使用絕對路徑) 'file_monitor' => false, // 是否開啓PHP文件更改監控(調試模式下自動開啓) 'file_monitor_interval' => 2, // 文件變化監控檢測時間間隔(秒) 'file_monitor_path' => [], // 文件監控目錄 默認監控application和config目錄 // 能夠支持swoole的全部配置參數 'pid_file' => Env::get('runtime_path') . 'swoole.pid', 'log_file' => Env::get('runtime_path') . 'swoole.log', 'document_root' => Env::get('root_path') . 'public', 'enable_static_handler' => true, 'timer' => true,//是否開啓系統定時器 'interval' => 500,//系統定時器 時間間隔 'task_worker_num' => 1,//swoole 任務工做進程數量 /** * 自定義投遞任務 * @param swoole_server $serv * @param int $taskId * @param int $srcWorkerId * @param mixed $data */ 'Task' => function($serv, $taskId, $srcWorkerId, $data){ $taskObj = new Task(); $classMethods = get_class_methods(Task::class); if (!in_array($data['method'], $classMethods)) { return 'method:'.$data['method'].' not find in'.Task::class; } return call_user_func_array([$taskObj, $data['method']], $data['params']); }, /** * onTask事件中沒有調用finish方法或者return結果,worker進程不會觸發onFinish * @Param swoole_server $serv * @param int $taskId 任務的ID * @param string $data 任務處理的結果內容 */ 'Finish' => function ($serv, $taskId, $data) { // echo 'taskId:' . $taskId . PHP_EOL; echo 'Finished:' . $data; Log::record($data); } ];
Index控制器中:
<?php namespace app\index\controller; use app\common\lib\task\SmsTask; use app\common\lib\utils\Tool;use think\Controller; use think\Request; class Index extends Controller {
public function sendSms(Request $request) { $result = $this->validate($request->post(), ['mobile' => 'require|mobile']); if (true !== $result) { return Tool::json('', $result, 250); } $mobile = $request->post('mobile'); // 一、使用topthink/swoole自帶的任務投遞方式,傳遞參數必須是對象或者swoole回調函數 // $smsObj = new SmsTask($mobile); // app('swoole')->task($smsObj); // app('swoole')->task($smsObj); // 二、自定義任務投遞方式 app('swoole')->task(Tool::taskParam('sendSms', (array)$mobile)); return Tool::json('', '短信發送成功'); }
SmsTask.php
使用系統默認的回調模板,
且投遞的參數必須是對象或者swoole回調函數,
投遞任務後默認會執行 run()方法或者swoole回調函數
<?php namespace app\common\lib\task; use Fairy\SmsSender; use think\facade\Config; use think\swoole\template\Task; /** * 使用 topthink/swoole 自帶的Task任務 * Class SmsTask * @package app\common\lib\task */ class SmsTask extends Task { private $mobile; public function initialize($args) { // TODO: Implement initialize() method. $this->mobile = $args[0]; } public function run($serv, $taskId, $fromWorkerId) { // TODO: Implement run() method. $smsObj = SmsSender::getInstance(Config::get('mail.')); $bool = $smsObj->send($this->mobile); if ($bool) { return 'send sms to ' . $this->mobile . ' success'; } else { return $smsObj->getError(); } } }
Task.php
配合swoole.php中自定義的 task 回調函數使用
<?php namespace app\common\lib\utils; use Fairy\SmsSender;use think\facade\Config; /** * 異步任務類 * Class Task * @package app\common\lib\utils */ class Task { /** * 異步發送短信 * @param $mobile * @return mixed|string * @throws \ErrorException */ public function sendSms($mobile) { $smsObj = SmsSender::getInstance(Config::get('sms.')); $bool = $smsObj->send($mobile); if ($bool) { return 'send sms to ' . $mobile . ' success'; } else { return 'send sms to ' . $mobile . ' failed: ' . $smsObj->getError(); } } }
參考:
https://www.kancloud.cn/manual/thinkphp5_1/675277