Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Swoole 2.0 is released, and the co-program feature supports PHP 7


May 14, 2021 Swoole



The official version of Swoole 2.0 has been released. T he biggest update to version 2.0 is the increased support for Coroutine. B oth PHP5 and PHP7 are supported in the official version. B ased on Swoole 2.0 co-program PHP developers can write code in a synchronized manner, the underlying automatic co-scheduling, into asynchronous IO. Solves the problem of traditional asynchronous programming nested callbacks.

Compared to the .js implementation of yield/generator, async/await in languages such as Node .js (ES6 plus), Python, etc., the Swoole co-program does not need to modify the code to add additional keywords.

Compared to gooutine in the Go language, the Swoole co-program is built-in, and the application layer code does not need to add go keywords to start the co-program, only need to use the encapsulated co-program client, it is easier to use. In addition, the IO component of the Swoole co-program has a time-out mechanism built into the underlying layer, which does not require the use of complex select/chan/timer to implement client time-outs.

Currently, the built-in co-program client components at the bottom of Swoole include: udpclient, tcpclient, httpclient, redisclient, and mysqlclient, which basically cover several communication protocols commonly used by developers. Co-program components can only be used in the server's onConnect, onRequest, onReceive, onMessage callback functions.

Using examples:

$server = new Swoole\Http\Server('127.0.0.1', 9501);

/*
    触发on request事件时,SWOOLE会开辟一个协程栈,对协程栈进行初始化
 */
$server->on('Request', function ($request, $response) {
    $tcp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_TCP);
    /**
        client在调用connect函数后,SWOOLE会将PHP上下文信息保存到当前栈内
        然后将协程挂起,待确认连接成功后,触发epoll事件,然后协程切换
        恢复PHP上下文信息,返回结果,继续执行PHP代码
     */
    if ($tcp_cli->connect('127.0.0.1', 9906) === false) {
        $response->end("connect server failed.");
        return;
    }
    $tcp_cli->send('test for the coro');
    /*
        client在调用recv函数后,SWOOLE会将PHP上下文信息保存到当前栈内
        然后将协程挂起待后端svr回包,触发epoll事件,然后协程切换
        恢复PHP上下文信息,返回结果,继续执行PHP代码
        如果后端在设定的超时时间内,未能回包,返回false
        client的errCode定为110
     */
    $ret = $tcp_cli->recv(100);
    $tcp_cli->close();
    if ($ret) {
        $response->end(" swoole response is ok");
    } else {
        $response->end(" recv failed error : {$tcp_cli->errCode}");
    }
});

$server->start();

UDP client

$udp_cli = new Swoole\Coroutine\Client(SWOOLE_SOCK_UDP);

$ret = $udp_cli->connect('127.0.0.1', 9906);
$udp_cli->send('test for the coro');

$ret = $udp_cli->recv(100);
$udp_cli->close();

if ($ret)
{
    $response->end("swoole response is ok");
}
else
{
    $response->end("recv failed error : {$client->errCode}");
}

MySQL client

$swoole_mysql = new Swoole\Coroutine\MySQL();
$swoole_mysql->connect([
    'host' => '127.0.0.1',
    'user' => 'user',
    'password' => 'pass',
    'database' => 'test'
]);
$res = $swoole_mysql->query('select sleep(1)');

Redis client

$redis = new Swoole\Coroutine\Redis();
$redis->connect('127.0.0.1', 6379);
$val = $redis->get('key');

Http client

$cli = new Swoole\Coroutine\Http\Client('127.0.0.1', 80);
$cli->setHeaders([
    'Host' => "localhost",
    "User-Agent" => 'Chrome/49.0.2587.3',
    'Accept' => 'text/html,application/xhtml+xml,application/xml',
    'Accept-Encoding' => 'gzip',
]);
$cli->set([ 'timeout' => 1]);
$cli->get('/index.php');
echo $cli->body;  
$cli->close();