php swoole -- 新手应该绕过的坑01 --task进程 协程

郑哲彦
2023-12-01

SOOWLE 版本:4.3.3 及以下 (笔者测试这里只有4.3.3 和4.2.1)
swoole 中在task进程里是无法使用协程相关,以下代码运行会报错。
worker 进程里就没问这个问题,可以放心使用。
原因:
RFC-1014提案使TaskWorker内可以使用异步和协程API。由于Task设计之初未考虑支持异步和协程。(4.2.12之后修改了)
文档地址:https://wiki.swoole.com/wiki/page/163.html
解决方案:
启用参数:task_enable_coroutine
文档地址:https://wiki.swoole.com/wiki/page/p-task_enable_coroutine.html
PS: 官方文档的话,新手可能看起来感觉一脸懵逼,不过还是要仔细研究,推敲,写文档的估计是个高手,很多东西都是一笔带过的。
错误信息:

[2019-06-21 11:02:02 ^15023.4]  ERROR   zm_deactivate_swoole (ERRNO 503): Fatal error: Swoole\Coroutine\MySQL::connect(): Unable to use async-io in task processes, please set `task_enable_coroutine` to true in /root/swoole/workertask.php on line 36
[2019-06-21 11:02:02 $15019.0]  WARNING swManager_check_exit_status: worker#4[pid=15023] abnormal exit, status=255, signal=0
Swoole\Coroutine\MySQL::connect(): Unable to use async-io in task processes, please set `task_enable_coroutine` to true in /root/swoole/workertask.php on line 36
^C
[root@study swoole]# php workertask.php
Client:Connect.
PHP Fatal error:  go(): Unable to use async-io in task processes, please set `task_enable_coroutine` to true in /root/swoole/workertask.php on line 29
[2019-06-21 11:14:50 ^15677.2]  ERROR   zm_deactivate_swoole (ERRNO 503): Fatal error: go(): Unable to use async-io in task processes, please set `task_enable_coroutine` to true in /root/swoole/workertask.php on line 29
[2019-06-21 11:14:50 $15675.0]  WARNING swManager_check_exit_status: worker#2[pid=15677] abnormal exit, status=255, signal=0

代码 01:

<?php

$http = new Swoole\Http\Server("0.0.0.0", 9501);
$http->set(array(
    'worker_num' => 2,
    'task_worker_num' => 10
));
$http->on('connect', function ($http, $fd) {
    echo "Client:Connect.\r\n";
});
$http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response)use($http) {
    $http->task(['task']);
    $response->end("<h1>Hello Swoole. #" . rand(1000, 9999) . "</h1>");
});

$http->on('Task', function (Swoole\Http\Server $server, $taskId, $workerId, $data) {

    $db = new Swoole\Coroutine\MySQL();
    $db->connect([
        'host' => '127.0.0.1',
        'port' => 3306,
        'user' => 'root',
        'password' => 'root',
        'database' => 'test',
    ]);
    $res = $db->query("select * from user limit 1");
    var_dump($res);

    $server->finish($data);
});
$http->on('Finish', function(Swoole\Http\Server $server, int $task_id, $data ) {
    var_dump($data);
});
$http->start();

代码 02:

<?php

$http = new Swoole\Http\Server("0.0.0.0", 9501);
$http->set(array(
    'worker_num' => 2,
    'task_worker_num' => 10
));
$http->on('connect', function ($http, $fd) {
    echo "Client:Connect.\r\n";
});
$http->on('request', function (Swoole\Http\Request $request, Swoole\Http\Response $response)use($http) {
    $http->task(['task']);
    $response->end("<h1>Hello Swoole. #" . rand(1000, 9999) . "</h1>");
});

$http->on('Task', function (Swoole\Http\Server $server, $taskId, $workerId, $data) {

    go(function() {
        $db = new Swoole\Coroutine\MySQL();
        $db->connect([
            'host' => '127.0.0.1',
            'port' => 3306,
            'user' => 'root',
            'password' => 'root',
            'database' => 'test',
        ]);
        $res = $db->query("select * from user limit 1");
        var_dump($res);
    });

    $server->finish($data);
});
$http->on('Finish', function(Swoole\Http\Server $server, int $task_id, $data ) {
    var_dump($data);
});
$http->start();

希望新手朋友们在遇到此问题的时候能够百度到这篇文章。
梅小春476984957@qq.com 2019年6月21日

 类似资料: