tp5 + swoole 结合巨坑, 网上完整的资料也少的资料, 解决方法也是千篇一律.
希望这篇博文,能让大家少踩坑.
我使用的是tp5.1 使用composer 安装如下:
composer create-project topthink/think=5.1.* tp5.1
首先按照Swoole官网说明安装swoole扩展,然后安装think-swoole扩展。
composer require topthink/think-swoole=2.0.*
直接在命令行下启动服务端
php think swoole
这样服务端就跑起来了, 今天swoole配置参看官方文档
比如我们需要使用swoole异步发送短信, 需要在使用异步的地方使用如下代码
$taskData = [
'method' => 'sendSms',
'data' => [
'phone' => $phoneNum,
'code' => $code,
]
];
//异步发送短信
app('swoole')->task($taskData);
‘method’ => ‘sendSms’ 即我们使用异步任务的哪个方法
‘data’ => [ ] 即我们使用异步任务的所需要传递的数据
配置文件swoole.php 代码如下:
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st
// +----------------------------------------------------------------------
use app\common\lib\task\Task;
use think\facade\Env;
// +----------------------------------------------------------------------
// | 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/static',
'enable_static_handler' => true,
'timer' => true,//是否开启系统定时器
'interval' => 500,//系统定时器 时间间隔
'task_worker_num' => 5,//swoole 任务工作进程数量
/**
* 自定义投递任务
* @param $serv
* @param int $taskId
* @param int $srcWorkerId
* @param mixed $data
*/
'Task' => function($serv, $taskId, $srcWorkerId, $data){
//分发task 任务机制, 让不同的任务 走不同的逻辑
$obj= new Task();
$method = $data['method'];
$flag= $obj->$method($data['data']);
if (!$flag){
return "异步任务方法".$method."失败 \n";
}
return "异步任务方法".$method."成功";
},
/**
* onTask事件中没有调用finish方法或者return结果,worker进程不会触发onFinish
* @Param swoole_server $serv
* @param int $taskId 任务的ID
* @param string $data 任务处理的结果内容
*/
'Finish' => function ($serv, $taskId, $data) {
echo 'Finished:' . $data;
}
];
注意:下面这行代码最重要
app('swoole')->task($taskData);
会调用swoole.php配置文件 的Task
另外,我们还需要创建Task 类处理异步分发任务
/**
* swoole 里面后续所有task 异步任务 都放这里来
* Created by 勇哥.
* Email: [email protected]
* 2019-10-20
*/
namespace app\common\lib\task;
use app\common\lib\ali\Sms;
use app\common\lib\Predis;
use app\common\lib\Redis;
class Task
{
//异步发送短信验证码
public function sendSms($data){
$phone = $data['phone'];
$code = $data['code'];
try{
$respon = Sms::send_alisms($phone , $code);
}catch (\Exception $e){
echo $e->getMessage()."\n";
return false;
}
if($respon ['Code'] === "OK") {
// redis
Predis::getInstance()->set(Redis::smsKey($phone), $code, config('redis.out_time'));
}else{
return false;
}
print_r($respon);
return true;
}
}
最后 tp5 swoole task 异步任务分发就完成了, 不需要该tp5 框架的源码, 不存在, GET, POST 请求获取不到的问题, 也不存在只能访问index 方法, 其他方法访问不到的问题.
如果需要使用swoole onMessage 或 onClose 方法 请参考下面的博客
https://www.cnblogs.com/cshaptx4869/p/11367137.html