Swoole协程并发调用
Swoole协程并发调用实现原理:
- 在onRequest中需要并发两个http请求,可使用go函数创建 2 个子协程,并发地请求多个URL;
- 并创建一个chan,使用use必报引用语法,传递给子协程;
- 主协程循环调用chan-pop,等待子协程完成任务,yield进入挂起状态;
- 并发的两个子协程其中某个完成请求时,调用chan-push将数据推送给主协程;
- 子协程完成URL请求后退出,主协程从挂起状态中恢复,继续向下执行调用$response-end发送响应结果。
第一步:编写代码
文件:d14.php
<?php
use Swoole\Coroutine\MySQL;
use Swoole\Coroutine\Redis;
// 创建HTTP服务器
$serv = new Swoole\Http\Server("127.0.0.1", 9503, SWOOLE_BASE);
// 监听
$serv->on('Request', function ($res, $resp) {
	// 创建通道
	$chan = new chan(2);
	// 创建协程
	go(function () use ($chan) {
		var_dump(time());
		// 连接mysql
		$mysql = new MySQL();
		$mysql->connect([
        'host'     => '127.0.0.1',
        'user'     => 'root',
        'password' => '123456',
        'database' => 'test',
    	]);
    	$result = $mysql->query('select sleep(3)');
    	// 将结果推送给主协程
		$chan->push($result);
	});
	go(function () use ($chan) {
		var_dump(time());
		$redis1 = new Redis();
    	$redis1->connect('127.0.0.1', 6379);
    	$result = $redis1->set('hello','swoole');
    	$chan->push($result);
	});
	go(function () use ($chan) {
		var_dump(time());
		$redis2 = new Redis();
    	$redis2->connect('127.0.0.1', 6379);
    	$result = $redis2->get('hello');
    	$chan->push($result);
	});
	// 从通道中读取数据并存入数组
	$results = [];
	for ($i = 0; $i < 3; $i++) {
		$results[] = $chan->pop();
	}
	// 响应请求
	$resp->end(json_encode([
		'data'	=>	$results,
		'time'	=>	time()
	]));
});
$serv->start();
第二步:运行http服务器
php d14.php
第三步:浏览器中访问
http://192.168.172.130:9503/
// 页面输出结果
{"data":["swoole",true,[{"sleep(3)":"0"}]],"time":1619270058}
第四步:查看http服务器
int(1619270058)
int(1619270058)
int(1619270058)
可以看到打印三个客户端请求时间是一致的,说明它们是并发执行的。
2021-04-21
请登录后再评论