执行异步任务 [编辑本页]

在Server程序中如果需要执行很耗时的操作,比如一个聊天服务器发送广播,Web服务器中发送邮件。如果直接去执行这些函数就会阻塞当前进程,导致服务器响应变慢。

Swoole提供了异步任务处理的功能,可以投递一个异步任务到TaskWorker进程池中执行,不影响当前请求的处理速度。

程序代码

基于第一个TCP服务器,只需要增加onTaskonFinish2个事件回调函数即可。另外需要设置task进程数量,可以根据任务的耗时和任务量配置适量的task进程。

$serv = new swoole_server("127.0.0.1", 9501);

//设置异步任务的工作进程数量
$serv->set(array('task_worker_num' => 4));

$serv->on('receive', function($serv, $fd, $from_id, $data) {
    //投递异步任务
    $task_id = $serv->task($data);
    echo "Dispath AsyncTask: id=$task_id\n";
});

//处理异步任务
$serv->on('task', function ($serv, $task_id, $from_id, $data) {
    echo "New AsyncTask[id=$task_id]".PHP_EOL;
    //返回任务执行的结果
    $serv->finish("$data -> OK");
});

//处理异步任务的结果
$serv->on('finish', function ($serv, $task_id, $data) {
    echo "AsyncTask[$task_id] Finish: $data".PHP_EOL;
});

$serv->start();

调用$serv->task()后,程序立即返回,继续向下执行代码。onTask回调函数Task进程池内被异步执行。执行完成后调用$serv->finish()返回结果。

finish操作是可选的,也可以不返回任何结果


  • 陈镇海

    task没任何返回输出啊 怎么回事

  • lee

    //$serv->finish("$data -> OK");

  • huaixiaoya

    $serv->on('task') 这个里面不能使用 swoole_timer_after() 定时器方法 会报错 大家注意下

  • 蝶恋花

    可以用这个方法,只是 swoole_timer_after(3000,function(){})的回调函数是不能识别$serv->on('task', function ($serv, $task_id, $from_id, $data) { echo "New AsyncTask[id=$task_id]".PHP_EOL; //返回任务执行的结果 $serv->finish("$data -> OK"); });中的$serv,$task_id,$from_id,$data这些参数,即使传参进去也不能识别

  • 老鬼行帮

    @陈镇海,服务启动后,需要客户端连接才会启动,才会有输出 telnet 127.0.0.1 9501 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. echo

    php async_server.php Dispath AysncTask:id=0 New AsyncTask[id=0] Dispath AysncTask:id=1 New AsyncTask[id=1] Dispath AysncTask:id=2 New AsyncTask[id=2] Dispath AysncTask:id=3

  • qhc39

    可以,得用闭包use(/显式传入需要用到的参数/)方式,就可以了。

  • 飞鸿影

    task回调里直接return不使用$serv->finish("$data -> OK");finish回调里也能收到数据。

  • 永恒

    请问是不是在task 里面调用处理业务的程序? 小白 不是很懂

  • 。

    不是很明白 设置的任务进程数怎么计算 $serv->set(array('task_worker_num' => 4));