本想自己适配的,奈何keng貌似不少,所以果断选择官方提供的包来适配233。。。

默认条件:thinkphp5.1.*版本下,且安装了swoole扩展

主要演示:task 任务的投递

友情提示:在swoole启动框架时,需注意静态变量的使用,会常驻内存(比如单例的变量),... 无图言卵,我么的口号是有图有真相(搞事)

以下是swoole下单例模式发送邮件:

请看收件人, 图一给 994xxx@qq.com发送邮件; 图二给 159xxx@qq.com 发送邮件,其收件人却有两(包含图一中的账号)。

找寻原因: 
由于使用的是单例模式邮件发送,其$phpmail对象只实例化一次 ,图一当添加收件人时 $shouJianRen[ ] = 994xxx@qq.com 结束;图二给 159xxx@qq.com 发送邮件,由于$phpmail对象不会再次实例化 也就是此时他的属性 $shouJianRen 已不再是空值,继而会继续叠加第二个收件人,所以也就造成了第二次给 159xxx@qq.com发送时会有两个收件人。 
 
以下开始正文。。。

一、安装

composer require topthink/think-swoole=2.0.*

二、使用

如果你要运行 swoole 的 http 服务器来启动 thinkPHP框架,执行

php think swoole

默认启动完成后,会在0.0.0.0:9501启动一个HTTP Server,可以直接访问当前的应用。

swoole的参数可以在应用配置目录下的 swoole.php 里面配置,配置详情见 thinkPHP官网

扩展中定义了 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'); // 1、使用topthink/swoole自带的任务投递方式,传递参数必须是对象或者swoole回调函数
// $smsObj = new SmsTask($mobile);
// app('swoole')->task($smsObj);
// app('swoole')->task($smsObj); // 2、自定义任务投递方式
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();
}
}
}

异步发送短信执行流程(拿自定义的task来举例):

  1. 配置swoole.php的自定义task函数
  2. 访问控制器 index/index/index 下的 sendSms() 方法 会投递一个任务,传递一些参数给task,此时接口数据已返回且短信发送任务也已投递
  3. task回调,也就是执行 swoole.php 中的配置的 task 函数
  4. 执行 finish 回调
  5. 打完收工,你学会了吗

参考:

https://www.kancloud.cn/manual/thinkphp5_1/675277

https://github.com/top-think/think-swoole/tree/v2.0.17

https://www.imooc.com/article/31751

topthink/think-swoole 扩展包的使用 之 Task的更多相关文章

  1. Ubuntu 16.04 swoole扩展安装注意!!!

    前言:目前很多项目估计常常会用到swoole扩展,如个人使用Ubuntu虚拟机安装扩展,这里总结一下遇到的问题: 一.先保证服务器时间同步当前地区时间,如北京时间: 1.设定时区 如:设定时区:dpk ...

  2. 【原】用PHP搭建基于swoole扩展的socket服务(附PHP扩展的安装步骤及Linux/shell在线手册)

    最近公司的一项目中,需要用PHP搭建一个socket服务. 本来PHP是不适合做服务的,因为和第三方合作,需要采用高效而稳定的TCP协议进行数据通信.经过多次尝试,最终选择了开源的PHP扩展:swoo ...

  3. Windows下用Composer引入官方GitHub扩展包

    Windows下用Composer引入官方GitHub扩展包 1. 当你打开威武RC4版本的链接的时候,往下拉你可以看到这个,然后你要做的就是想到,百度Composer,看看是个什么鬼,别想太多,跟着 ...

  4. Windows下swoole扩展的编译安装部署

    1. 到cygwin官网下载cygwin. 官网地址:https://www.cygwin.com/ 2. 打开下载好的cygwin安装包,开始安装cygwin. 选择cygwin的安装目录(这个同时 ...

  5. linux下搭建lamp环境以及安装swoole扩展

    linux下搭建lamp环境以及安装swoole扩展   一.CentOS 6.5使用yum快速搭建LAMP环境 准备工作:先更新一下yum源  我安装的环境是:apache2.2.15+mysql5 ...

  6. Mac系统下 PHP7安装Swoole扩展 教程

    转载自 https://www.fujieace.com/php/php-extensions/swoole.html 今天我用的PHP版本是:PHP7.1 环境依赖: php-5.3.10 或更高版 ...

  7. thinkphp5 Windows下用Composer引入官方GitHub扩展包

    很多新手,比如说我,写代码就是在windows下,所以总会遇到很多不方便的地方,比如说GitHub上面的代码更新了,要是你在linux,只要几行命令就可以搞定更新了,在windows下面,你需要用到C ...

  8. php swoole扩展安装

    一波三折. 首先下载swoole安装包(由于我这里php是7,所以说应该去官网下载最新的swoole包,否则会发生意想不到的错误) wget https://github.com/swoole/swo ...

  9. 转 linux安装swoole扩展

    linux安装swoole扩展 发表于2年前(2014-09-03 14:05)   阅读(4404) | 评论(3) 7人收藏此文章, 我要收藏 赞2 上海源创会5月15日与你相约[玫瑰里],赶快来 ...

随机推荐

  1. centos7.5下安装jenkins

    最近从头搭建了一套python+selenium+pytest+allure+Jenkins的环境,虽然网上挺多的,不过还是记录下来,毕竟坑还是挺多的....... 先从搭建jenkins开始把! 方 ...

  2. django的静态文件配置和路由控制

    上一篇写到刚建完django项目,此时我登录页面中调用了js文件,执行后发现报错了找不到js这个文件 目录结构如图所示: <!DOCTYPE html> <html lang=&qu ...

  3. @Value注解的使用

    前提它需要在spring 管理的Bean中有效 (如@Service...) #{...} 此方式可以使用 SpEL 表达式如 #{30-15} ${...} 可以获取配置文件中的值 如 ${jwt. ...

  4. 解决IDEA快捷键 Alt+Insert 失效的问题

    现象 IDEA快捷键 Alt+Inser 失效,单击右键也不出现[Generate]. 这个问题经常出现在重新安装IDEA后. 原因 缺少2个插件 解决办法 在setting中启用这2个插件即可.这2 ...

  5. 重新梳理IT知识之java-01语法(一)

    标识符的命名规范 包名:xxxyyyzzz 类名.接口名:XxxYyyZzz (大驼峰) 变量名.方法名:xxxYyyZzz 常量名:XXX_YYY_ZZZ //**************强制类型转 ...

  6. 如果谷歌浏览器突然打不开网页,而且显示:"网页可能暂时无法连接,或者它已永久性地移动到了新网址,返回ERR_TUNNEL_CONNECTION_FAILED",怎么办?用这个方法,亲试有效!!!

    打开cmd: 依次输入: ipconfig /flushdnsnbtstat –rnetsh int ip resetnetsh winsock reset 效果图 然后我的浏览器就能正常使用了,很有 ...

  7. Fleck WebSocket使用

    Fleck WebSocket使用 作为笔记存储. 最近公司有这方面的使用需求.在网上查了一些资料后.得到了想要的结果.以下记录摘抄至网上资料. 1.首先,服务端.项目NuGet直接引用Fleck类库 ...

  8. Could not find a version that satisfies the requirement win32api (from versions: ) No matching distribution found for win32api

    pip install win32api pip install pywin32 都会提示错误,如下: Could not find a version that satisfies the requ ...

  9. 理解WPF中的视觉树和逻辑树

    轉載地址:http://blog.csdn.net/changtianshuiyue/article/details/26981797 理解WPF中的视觉树和逻辑树  Understanding th ...

  10. Day11 - Q - A Multiplication Game HDU - 1517

    题目链接 本题很像bash博弈,但又有些许不同,因为这里是乘法,我们可以列出前几项可能 若n=2-9,那么first可以一次取完 若n=10-18,无论first怎么取,second都能一次取完 若n ...