swoole4.0可使用协程+通道的全新编程模式,代替异步回调,应用层可使用完全同步的编程方式,底层自动实现异步I/O
下面会通过一段代码,来帮助大家理解swoole的协程
<?php use Swoole\Coroutine\Http\Client; //此方法记录执行时间 function timediff($time) { return microtime(true) - $time; } //创建http server $http = new Swoole\Http\Server("0.0.0.0", 9501); $http->set([ //"daemonize" => true, "worker_num" => 1, ]); $http->on('request', function ($request, $response) { //浏览器会自动发起这个请求,这也是很多人碰到的一个问题: //为什么我浏览器打开网站,收到了两个请求? if ($request->server['path_info'] == '/favicon.ico') { $response->end(''); return; } $time = microtime(true); $response->header("content-type", "text/html; charset=UTF-8"); $response->write("1. 接受请求,此处被执行, 第" . __LINE__ . "行, 时间" . $time . "<br/>"); //启动第一个协程 go(function () use ($response) { $time = microtime(true); $response->write("2. 进入第一个协程,发起http请求taobao, 第" . __LINE__ . "行, 时间:" . $time . "<br/>"); //启动一个协程客户端client,请求淘宝首页 $cli = new Client('www.taobao.com', 443, true); $cli->setHeaders([ 'Host' => "www.taobao.com", "User-Agent" => 'Chrome/49.0.2587.3', 'Accept' => 'text/html,application/xhtml+xml,application/xml', 'Accept-Encoding' => 'gzip', ]); $cli->set(['timeout' => 1]); //调用get方法,协程挂起, $cli->get('/index.php'); //会等待i/o数据返回,才会继续执行下面 $response->write("7. get回taobao数据,唤起协程,此处被执行, 第" . __LINE__ . "行, 执行时间" . timediff($time) . "<br/>"); $cli->close(); }); //上面get挂起协程后,后立马执行这一行 $response->write("3 cli->get时挂起协程了,此处被执行,不会被阻塞, 第" . __LINE__ . "行, 时间:" . microtime(true) . "<br/>"); //启动第二个协程 go(function () use ($response) { $time = microtime(true); $response->write("4. 进入第二个协程,发起http请求baidu, 第" . __LINE__ . "行, 时间:" . $time . "<br/>"); //启动一个协程客户端client,请求百度首页 $cli = new Client('www.baidu.com', 443, true); $cli->setHeaders([ 'Host' => "www.baidu.com", "User-Agent" => 'Chrome/49.0.2587.3', 'Accept' => 'text/html,application/xhtml+xml,application/xml', 'Accept-Encoding' => 'gzip', ]); $cli->set(['timeout' => 1]); //调用get方法,协程挂起, $cli->get('/index.php'); //会等待i/o数据返回,才会继续执行下面 $response->write("6. get回baidu数据,唤起协程,此处被执行,正常这个先返回,因为ping百度更快,说明两个协程也是并发执行的, 第" . __LINE__ . "行, 执行时间" . timediff($time) . "<br/>"); $cli->close(); }); //第二个协程get时挂起,执行到这一步 $response->write("5 cli->get时挂起协程了,此处被执行,不会被阻塞, 第" . __LINE__ . "行, 时间:" . microtime(true) . "<br/>"); }); $http->start();
运行
1、保存为http.php
2、执行 php http.php
3、浏览器打开:http://127.0.0.1:9501/
几个关键点:
Swoole的协程是单进程的
代码遇到i/o操作会挂起协程
协程之间是并发的,相互不堵塞
预告:下一篇用代码实现类似golang的waitgroup功能
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/6161/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料
查 看2022高级编程视频教程免费获取