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();