Amp event loop for Workerman
This repository has been archived on 2017-08-18. You can view files and clone it, but cannot push or open issues or pull requests.
Go to file
CismonX 39c8afa223
archive
2017-08-18 23:26:46 +08:00
src archive 2017-08-18 23:26:46 +08:00
.gitignore archive 2017-08-18 23:26:46 +08:00
LICENSE archive 2017-08-18 23:26:46 +08:00
README.md archive 2017-08-18 23:26:46 +08:00
composer.json archive 2017-08-18 23:26:46 +08:00

README.md

Workerman-Amp

概述

Amp 是一个事件驱动的 PHP 框架,与 ReactPHP 类似。

本项目用于将 Amp 的 event-loop 应用于 Workerman从而可以在 Workerman 中使用基于 Amp 的高性能组件,例如异步 MySQL异步 Redis异步 HTTP 客户端等。

笔者修改了本项目的源码,使其兼容原生 Amp。现在无需修改 Amp 的源码就可以在项目中使用其所有组件。以后笔者可能会发布一些 Demo。

使用说明

  1. 使用 composer 将 Workerman\Events\Amp 加载到项目中。
composer require cismonx/workerman-amp
  1. 将 Amp 设置为 Workerman 所使用的 event-loop。如下
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 有效。

  2. 目前只能在 onConnect onSslHandshake onMessage 这三个事件回调函数中使用 Amp 协程。

以下是使用 Amp 协程的示例(测试的时候同时多发几条请求,可以看出效果)

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