在Server程序中如果需要执行很耗时的操作,比如一个聊天服务器发送广播,Web服务器中发送邮件。如果直接去执行这些函数就会阻塞当前进程,导致服务器响应变慢。
模拟业务场景:使用form表单提交数据,完成注册并发送激活邮件的功能。
客户端提交post数据->服务器获取到数据->完成注册将用户数据写入数据库->发送账号激活邮件->返回客户端提示注册成功。
这个业务逻辑是没有问题的,但是由于发送邮件是一个耗时操作(比如2-3s)并且会同步阻塞程序的执行,直到发送成功以后响应到客户端提示注册成功。这个过程中用户从提交到最后得到注册成功的提示估计需要4s左右,一次请求响应需要4s这肯定是不合理的!
现在使用Task异步任务投递可以大大提升用户体验,大致流程:
客户端提交post数据->服务器获取到数据->完成注册将用户数据写入数据库->马上返回客户端提示注册成功
在注册成功同时投递一个task任务->异步完成邮件发送的耗时操作 (这部分时间用户是无感知的,因为很早已经响应回客户端了)。
如何使用Think-Swoole的Task异步任务投递:
定义事件监听类(php think make:listener 类名)
app/event.php文件中定义swoole.task的事件监听
获取到Swoole/Server对象调用task方法(参数中传递刚刚定义的监听类)
在刚刚定义的事件监听类的handle方法中定义触发回调逻辑代码
调用触发task任务完成后的finish方法(需要才调用,非必须)
根据上面流程,完成一次实操:
进入tp61根目录运行:php think make:listener TaskTest
自动生成了app\listener\TaskTest事件监听类
在app/event.php中的数组listen
键中定义swoole.task事件的监听
之后编辑异步文件代码
之后在任意方法中调用task异步的事件 (三种方法都可以 任选)
//方法一
public function tasktest(){$swoole = app('swoole.server');$swoole -> task(\app\listener\TaskTest::class);echo "成功";}
方法二
public function tasktest(\Swoole\Server $server){$server -> task(\app\listener\TaskTest::class); echo "成功";}
方法三
public function tasktest(\think\swoole\Manager $manager){$manager->getServer() -> task(\app\listener\TaskTest::class);echo "成功";}