Workerman 5.0 版本中的异步HTTP协程客户端组件是一个基于PHP协程的高性能HTTP客户端,它能够充分利用PHP的异步特性来提高HTTP请求的效率和性能。这个组件允许开发者在编写PHP代码时,以同步的方式发送异步HTTP请求,从而使得编写的代码更加简洁易懂,同时也能够处理大量的并发请求。
“这个组件的特点包括:
“注意:
5.0
需要PHP版本大于8.2.4
及以上版本
通过php -v
查看你当前PHP版本信息
php -v
PHP 8.2.18 (cli) (built: Apr 11 2024 19:20:54) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.18, Copyright (c) Zend Technologies
with Zend OPcache v8.2.18, Copyright (c), by Zend Technologies
composer require workerman/workerman v5.0.0-beta.7
“Revolt是什么?
Revolt
是并发PHP应用程序的坚如磐石的事件循环。通常的PHP应用程序将大部分时间花在等待I/O
上。虽然PHP是单线程的,但可以使用协作多任务来允许并发性,方法是使用等待时间来做不同的事情。
PHP的传统同步执行流程很容易理解。一次只做一件事。如果查询数据库,则发送查询并等待数据库服务器的响应。一旦你有了答案,你就可以开始做下一件事。
ReactPHP和其他库已经在PHP中提供了很长一段时间的协作多任务。然而,它们的事件驱动特性与许多现有的接口不兼容,需要不同的思维模型。PHP 8.1内置了fibers
,它提供了协作多线程。调用可以是异步的,没有promise
或回调,同时仍然允许非阻塞I/O
。
每个使用协同多任务的应用程序都需要一个调度器(也称为事件循环),这个包提供了这个调度器。Revolt
是结合了React和ReactPHP的事件循环实现的多年经验的结果。然而,它并不是一个用于编写并发PHP应用程序的成熟框架,而只是提供了必要的公共基础。不同的(强烈的)固执己见的库可以在它的基础上构建,React和ReactPHP将继续共存。
“Revolt 支持事件
Defer
回调在事件循环的下一次迭代中执行。如果有延迟调度,事件循环不会在迭代之间等待。Delay
在指定的秒数后执行回调。秒的分数可以表示为浮点数。Repeat
在指定的秒数后重复执行回调。秒的分数可以表示为浮点数。Stream readable
当流上有数据要读取或连接关闭时,将执行回调。Stream writable
当写缓冲区中有足够的空间来接受要写入的新数据时,就会执行回调。Signal
当进程从操作系统接收到特定信号时执行回调。“安装
composer require revolt/event-loop
“
workerman/http-client
是一个异步http客户端组件。所有请求响应异步非阻塞,内置连接池,消息请求和响应符合PSR7规范。更多了解:https://www.workerman.net/doc/workerman/components/workerman-http-client.html
composer require workerman/http-client
http.php
伪代码
<?php
/**
* @desc 伪代码
* @author Tinywan(ShaoBo Wan)
* @date 2024/11/14 15:14
*/
declare(strict_types=1);
use Workerman\Worker;
require_once '../vendor/autoload.php';
try {
$worker = new Worker();
$worker->onWorkerStart = function () {
$http = new Workerman\Http\Client();
$response = $http->get('https://www.tinywan.com/');
var_dump($response->getStatusCode());
echo $response->getBody() . PHP_EOL;
$response = $http->post('https://www.tinywan.com/', ['key1' => 'value1', 'key2' => 'value2']);
var_dump($response->getStatusCode());
echo $response->getBody() . PHP_EOL;
$response = $http->request('https://www.tinywan.com/', [
'method' => 'GET',
'version' => '1.1',
'headers' => ['Connection' => 'keep-alive'],
'data' => ['key1' => 'value1', 'key2' => 'value2'],
]);
echo $response->getBody() . PHP_EOL;
};
Worker::runAll();
} catch (Throwable $throwable) {
var_dump($throwable->getMessage());
}
/var/www/workerman5.x-demo/coroutine # php http.php start
Workerman[http.php] start in USER mode
---------------------------------------- WORKERMAN -----------------------------------------
Workerman version:5.0.0-beta.7 PHP version:8.2.18 Event-loop:Workerman\Events\Revolt
----------------------------------------- WORKERS ------------------------------------------
proto user worker listen processes state
tcp root none none 1 [OK]
--------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
“注意:这里使用
Event-loop:Workerman\Events\Revolt
事件
执行结果
int(200)
int(405)
int(200)
<?php
/**
* @desc 伪代码
* @author Tinywan(ShaoBo Wan)
* @date 2024/11/14 15:14
*/
declare(strict_types=1);
use Workerman\Worker;
use \Workerman\Connection\TcpConnection;
use \Workerman\Protocols\Http\Request;
require_once '../vendor/autoload.php';
// 创建一个Worker监听8217端口,使用http协议通讯
$httpWorker = new Worker("http://0.0.0.0:8217");
// 启动8个进程对外提供服务
$httpWorker->count = 8;
// 接收到浏览器发送的数据时回复给浏览器
$httpWorker->onMessage = function (TcpConnection $connection, Request $request) {
$http = new \Workerman\Http\Client();
$count = 50;
$result = [];
while ($count--) {
$startTime = microtime(true);
echo '开始时间:' . $startTime . PHP_EOL;
$response = $http->get('https://api.tinywan.com/systems/website');
$endTime = microtime(true);
echo '结束时间:' . $endTime . PHP_EOL;
$result[] = sprintf('第%d个 | 耗时%s秒 | 状态码%d', $count, $endTime - $startTime, $response->getStatusCode());
}
$connection->send(json_encode($result));
};
// 运行worker
Worker::runAll();
执行结果(未完,待续……)
[
"第49个 | 耗时0.53055596351624秒 | 状态码200",
"第48个 | 耗时0.11245107650757秒 | 状态码200",
"第47个 | 耗时0.13903284072876秒 | 状态码200",
"第46个 | 耗时0.21533107757568秒 | 状态码200",
"第45个 | 耗时0.11252999305725秒 | 状态码200",
"第44个 | 耗时0.15401482582092秒 | 状态码200",
"第43个 | 耗时0.10678505897522秒 | 状态码200",
"第42个 | 耗时0.099571943283081秒 | 状态码200",
"第41个 | 耗时0.12561202049255秒 | 状态码200",
"第40个 | 耗时0.10563802719116秒 | 状态码200",
"第39个 | 耗时0.11354088783264秒 | 状态码200",
"第38个 | 耗时0.1011688709259秒 | 状态码200",
"第37个 | 耗时0.20793986320496秒 | 状态码200",
"第36个 | 耗时0.1089551448822秒 | 状态码200",
"第35个 | 耗时0.092885971069336秒 | 状态码200",
"第34个 | 耗时0.10161209106445秒 | 状态码200",
"第33个 | 耗时0.20717096328735秒 | 状态码200",
"第32个 | 耗时0.20546984672546秒 | 状态码200",
"第31个 | 耗时0.11044192314148秒 | 状态码200",
"第30个 | 耗时0.12123489379883秒 | 状态码200",
"第29个 | 耗时0.11858606338501秒 | 状态码200",
"第28个 | 耗时0.17020511627197秒 | 状态码200",
"第27个 | 耗时0.095601081848145秒 | 状态码200",
"第26个 | 耗时0.11254286766052秒 | 状态码200",
"第25个 | 耗时0.19883704185486秒 | 状态码200",
"第24个 | 耗时0.20402407646179秒 | 状态码200",
"第23个 | 耗时0.10713791847229秒 | 状态码200",
"第22个 | 耗时0.11914396286011秒 | 状态码200",
"第21个 | 耗时0.094994068145752秒 | 状态码200",
"第20个 | 耗时0.10224294662476秒 | 状态码200",
"第19个 | 耗时0.11380887031555秒 | 状态码200",
"第18个 | 耗时0.10260701179504秒 | 状态码200",
"第17个 | 耗时0.28102612495422秒 | 状态码200",
"第16个 | 耗时0.10411977767944秒 | 状态码200",
"第15个 | 耗时0.10007786750793秒 | 状态码200",
"第14个 | 耗时0.095911979675293秒 | 状态码200",
"第13个 | 耗时0.094711065292358秒 | 状态码200",
"第12个 | 耗时0.09196400642395秒 | 状态码200",
"第11个 | 耗时0.10585021972656秒 | 状态码200",
"第10个 | 耗时0.092756032943726秒 | 状态码200",
"第9个 | 耗时0.23688101768494秒 | 状态码200",
"第8个 | 耗时0.20317101478577秒 | 状态码200",
"第7个 | 耗时0.10062909126282秒 | 状态码200",
"第6个 | 耗时0.20747685432434秒 | 状态码200",
"第5个 | 耗时0.11253881454468秒 | 状态码200",
"第4个 | 耗时0.12536215782166秒 | 状态码200",
"第3个 | 耗时0.17252016067505秒 | 状态码200",
"第2个 | 耗时0.12250709533691秒 | 状态码200",
"第1个 | 耗时0.10875701904297秒 | 状态码200",
"第0个 | 耗时0.10053586959839秒 | 状态码200"
]
“仓库地址:https://github.com/Tinywan/workerman5.x-demo