ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
我们可以在worker进程中投递一个异步任务到task_worker池中。此函数是非阻塞的,执行完毕会立即返回。worker进程可以继续处理新的请求。 通常会把耗时的任务交给task_worker来处理。 > 我们可以通过如下代码判断是Worker进程还是TaskWorker进程: ``` function onWorkerStart($serv, $worker_id) { if ($worker_id >= $serv->setting['worker_num']) { //超过worker_num,表示这是一个task进程 } } ``` 看一个示例: ``` php <?php $server = new \swoole_server("127.0.0.1",8088); $server->set(array( 'daemonize' => false, 'reactor_num' => 2, 'worker_num' => 1, 'task_worker_num' => 1, )); $server->on('start', function ($serv){ swoole_set_process_name("swoole_task_matser"); //主进程命名 }); $server->on('connect', function ($serv, $fd){ echo "client connect. fd is {$fd}\n"; }); $server->on('receive', function ($serv, $fd, $from_id, $data){ echo sprintf("onReceive. fd: %d , data: %s\n", $fd, json_encode($data) ); $serv->task(json_encode([ 'fd' => $fd, 'task_name' => 'send_email', 'email_content' => $data, 'email' => 'admin@qq.com' ])); }); $server->on('close', function ($serv, $fd){ echo "client close. fd is {$fd}\n"; }); $server->on('task', function (swoole_server $serv, $task_id, $from_id, $data){ echo $data; $data = json_decode($data, true); $serv->send($data['fd'], "send eamil to {$data['email']}, content is : {$data['email_content']}\n"); //echo 'task finished'; //return 'task finished'; $serv->finish('task finished'); }); $server->on('finish', function (swoole_server $serv, $task_id, $data){ echo 'onFinish:' .$data; }); $server -> start(); ``` 这里新建了一个tcp服务器,参数里设置`worker_num`进程为1,`task_worker_num`为1。 配置了`task_worker_num`参数后将会启用task功能,`swoole_server`务必要注册`onTask/onFinish`2个事件回调函数。如果没有注册,服务器程序将无法启动。 onTask回调接收4个参数,分别是serv对象、任务ID、自于哪个worker进程、任务的内容。注意的是,`$data`必须是字符串。我们可以在worker进程里使用`swoole_server->task ($data)`进行任务投递。 onFinish回调用于将处理结果告知worker进程,此回调必须有,但是否被调用由OnTask决定。在OnTask里使用`return`或者`finish()`可以将处理结果发生到onFinish回调,否则onFinish回调是不会被调用的。也就是说:`finish()`是可选的。如果worker进程不关心任务执行的结果,不需要调用此函数。onFinish回调里的`$data`同样必须是字符串。 我们新起一个窗口,使用`telnet`发送消息到服务端进行测试: client端: ``` telnet 127.0.0.1 8088 Trying 127.0.0.1... Connected to 127.0.0.1. hhh send eamil to admin@qq.com, content is : hhh ``` server端: ``` client connect. fd is 1 onReceive. fd: 1 , data: "hhh\r\n" {"fd":1,"task_name":"send_email","email_content":"hhh\r\n","email":"admin@qq.com"} onFinish:task finished ``` onFinish回调里不使用`return`或者`finish()`,我们将看不到server端最后一行输出。 此时服务器进程模型: ``` pstree -ap | grep swoole | | `-php,3190 swoole_task.php | | |-php,3192 swoole_task.php | | | |-php,3194 swoole_task.php | | | `-php,3195 swoole_task.php ``` 看到两个worker进程,其中一个是worker进程,另外一个是task_worker进程。