62 lines
2.2 KiB
Markdown
62 lines
2.2 KiB
Markdown
## Workerman-Amp
|
||
|
||
### 概述
|
||
|
||
[Amp](http://amphp.org/) 是一个事件驱动的 PHP 框架,与 ReactPHP 类似。
|
||
|
||
本项目用于将 Amp 的 event-loop 应用于 Workerman,从而可以在 Workerman 中使用基于 Amp 的高性能组件,例如异步 MySQL,异步 Redis,异步 HTTP 客户端等。
|
||
|
||
笔者修改了本项目的源码,使其兼容原生 Amp。现在无需修改 Amp 的源码就可以在项目中使用其所有组件。以后笔者可能会发布一些 Demo。
|
||
|
||
### 使用说明
|
||
|
||
1. 使用 composer 将 `Workerman\Events\Amp` 加载到项目中。
|
||
|
||
```bash
|
||
composer require cismonx/workerman-amp
|
||
```
|
||
|
||
2. 将 Amp 设置为 Workerman 所使用的 event-loop。如下:
|
||
|
||
```php
|
||
Worker::$eventLoopClass = '\\Workerman\\Events\\Amp';
|
||
```
|
||
|
||
### 兼容 Amp 协程
|
||
|
||
在 Amp 中,协程是一个十分重要的特性。对 Workerman 的源码稍加修改,将 watcher 回调中的同步调用(`call_user_func`)改为异步调用(`yield \Amp\call()`),即可在 Workerman 的事件回调函数中直接使用 Amp 协程。
|
||
|
||
以下几点需要注意:
|
||
|
||
1. 以上提到的对 Workerman 源码的修改在 src 目录下的 coroutine-compatibility.patch 中。这个补丁对 [Workerman-3.4.5-stable](https://github.com/walkor/Workerman/releases/tag/v3.4.5) 有效。
|
||
|
||
2. 目前只能在 `onConnect` `onSslHandshake` `onMessage` 这三个事件回调函数中使用 Amp 协程。
|
||
|
||
以下是使用 Amp 协程的示例(测试的时候同时多发几条请求,可以看出效果)
|
||
|
||
```php
|
||
use Workerman\Worker;
|
||
Worker::$eventLoopClass = '\\Workerman\\Events\\Amp';
|
||
$worker = new Worker('http://[::]:20080');
|
||
function subtractToZero($init, $interval) {
|
||
$value = $init;
|
||
$emitter = new Amp\Emitter;
|
||
$id = \Workerman\Lib\Timer::add($interval, function () use ($emitter, &$value, &$id) {
|
||
if ($value > 0)
|
||
$emitter->emit(--$value);
|
||
else {
|
||
$emitter->complete();
|
||
\Workerman\Lib\Timer::del($id);
|
||
}
|
||
});
|
||
return $emitter->iterate();
|
||
}
|
||
$worker->onMessage = function ($connection) {
|
||
$iterator = subtractToZero(10, 1);
|
||
while (yield $iterator->advance())
|
||
var_dump($iterator->getCurrent());
|
||
$connection->send('ok');
|
||
};
|
||
Worker::runAll();
|
||
```
|