???? 感謝兔子大佬
chaz6chez
的協(xié)程插件 http://m.wtbis.cn/plugin/167
???? webman-coroutine 是一個 webman 開發(fā)框架生態(tài)下的協(xié)程基建支撐插件。
Github:https://github.com/workbunny/webman-coroutine
主要實現(xiàn)以下功能:
workerman 4.x
的 swow 協(xié)程驅(qū)動能力,兼容workerman 5.x
版本自帶的swow
協(xié)程驅(qū)動;workerman 4.x
的 swoole 協(xié)程驅(qū)動能力,兼容workerman 5.x
版本自帶的swoole
協(xié)程驅(qū)動;coroutine web server
用于實現(xiàn)具備協(xié)程能力的 web 框架基建revolt
等workerman 4.x/5.x
驅(qū)動下的 webman 框架無法完整使用swoole
的協(xié)程能力,所以使用CoroutineWebServer
來替代webman
自帶的webServer
workerman 4.x
下還未有官方支持的swow
協(xié)程驅(qū)動,本插件提供SwowEvent
事件驅(qū)動支撐workerman 4.x
下的協(xié)程能力event-loop
等操作相較于普通開發(fā)會存在一定的心智負擔(dān),所以本插件提供了event_loop()
函數(shù),用于根據(jù)當前環(huán)境自動選擇合適的事件驅(qū)動通過
composer
安裝
composer require workbunny/webman-coroutine
注: 目前在開發(fā)階段,體驗請使用
dev-main
分支
# composer require workbunny/webman-coroutine dev-main
./composer.json has been updated
Running composer update workbunny/webman-coroutine
Loading composer repositories with package information
Updating dependencies
Lock file operations: 6 installs, 0 updates, 0 removals
- Locking composer/semver (3.4.2)
- Locking psr/http-client (1.0.3)
- Locking psr/http-factory (1.0.2)
- Locking psr/http-message (2.0)
- Locking swow/swow (v1.5.3)
- Locking workbunny/webman-coroutine (dev-main 3965bb5)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 6 installs, 0 updates, 0 removals
- Installing composer/semver (3.4.2): Extracting archive
- Installing psr/http-message (2.0): Extracting archive
- Installing psr/http-client (1.0.3): Extracting archive
- Installing psr/http-factory (1.0.2): Extracting archive
- Installing swow/swow (v1.5.3): Extracting archive
- Installing workbunny/webman-coroutine (dev-main 3965bb5): Extracting archive
> support\Plugin::install
> support\Plugin::install
> support\Plugin::install
> support\Plugin::install
> support\Plugin::install
> support\Plugin::install
Create config/plugin/workbunny/webman-coroutine
3 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating autoload files
12 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found.
enable : (true/false)
是否啟用協(xié)程webServer
port : (int)
協(xié)程webServer
默認端口channel_size : (int)
協(xié)程webServer
默認每個stream
的channel
容量./vendor/bin/swow-builder
安裝swow
拓展,注意請關(guān)閉swoole
環(huán)境config/server.php
中'event_loop' => \Workbunny\WebmanCoroutine\event_loop()
,event_loop()
函數(shù)會根據(jù)當前環(huán)境自行判斷當前的 workerman 版本,自動選擇合適的事件驅(qū)動
swow
拓展時,workerman 4.x
下使用SwowEvent
事件驅(qū)動swow
拓展時,workerman 5.x
下使用workerman
自帶的Swow
事件驅(qū)動swow
時,使用workerman
自帶的Event
事件驅(qū)動php -d extension=swow webman start
啟動CoroutineWebServer
注:
CoroutineWebServer
可以在config/plugin/workbunny/webman-coroutine/app.php
中通過enable=false
關(guān)閉啟動
通過以下命令啟動
php -d extension=swow webman start
啟動輸出
# php -d extension=swow webman start
Workerman[webman] start in DEBUG mode
----------------- WORKERMAN ------------------------------------
Workerman version:4.1.15 PHP version:8.3.9 Event-Loop:Workbunny\WebmanCoroutine\Events\SwowEvent
----------------- WORKERS ---------------------------------------
proto user worker listen processes status
tcp root webman http://0.0.0.0:8217 8 [OK]
tcp root monitor none 1 [OK]
tcp root push_chart none 1 [OK]
tcp root plugin.webman.push.server websocket://0.0.0.0:8788 1 [OK]
tcp root plugin.workbunny.webman-coroutine.coroutine-web-server http://[::]:8717 2 [OK]
------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.
pecl install swoole
安裝穩(wěn)定版 swoole 拓展swoole
加入php.ini
配置文件config/server.php
中'event_loop' => \Workbunny\WebmanCoroutine\event_loop()
,event_loop()
函數(shù)會根據(jù)當前環(huán)境自行判斷當前的 workerman 版本,自動選擇合適的事件驅(qū)動
php -d extension=swoole webman start
啟動config/plugin/workbunny/webman-coroutine/process.php
啟動的 CoroutineWebServer 可以用于協(xié)程環(huán)境開發(fā),原服務(wù)還是 BIO 模式composer require cclilshy/p-ripple-drive
安裝 ripple 驅(qū)動插件config/server.php
配置
'event_loop' => \Workbunny\WebmanCoroutine\event_loop()
自動判斷,請勿開啟 swow、swoole,'event_loop' => \Workbunny\WebmanCoroutine\Factory::RIPPLE_FIBER
手動指定php webman start
啟動注:該環(huán)境協(xié)程依賴
php-fiber
,并沒有自動hook
系統(tǒng)的阻塞函數(shù),但支持所有支持php-fiber
的插件
Workbunny\WebmanCoroutine\Handlers\HandlerInterface
接口,實現(xiàn)自定義協(xié)程處理邏輯Workbunny\WebmanCoroutine\Factory::register(HandlerInterface $handler)
注冊你的協(xié)程處理器config/server.php
中'event_loop' => {你的事件循環(huán)類}
CoroutineWebServer
接受處理協(xié)程請求注:
\Workbunny\WebmanCoroutine\event_loop()
自動判斷加載順序按\Workbunny\WebmanCoroutine\Factory::$_handlers
的順序執(zhí)行available()
擇先注:因為
eventLoopClass
與HandlerClass
是一一對應(yīng)的,所以建議不管是否存在相同的事件循環(huán)或者相同的處理器都需要繼承后重命名
webman-coroutine
提供了用于讓自己的自定義服務(wù)/進程協(xié)程化的基礎(chǔ)工具
注:考慮到 webman 框架默認不會啟用注解代理,所以這里沒有使用注解代理來處理協(xié)程化代理
假設(shè)我們已經(jīng)存在一個自定義服務(wù)類,如MyProcess.php
namespace process;
class MyProcess {
public function onWorkerStart() {
// 具體業(yè)務(wù)邏輯
}
// ...
}
在webman/workerman
環(huán)境中,onWorkerStart()
是一個 worker 進程所必不可少的方法,
假設(shè)我們想要將它協(xié)程化,在不改動MyProcess
的情況下,只需要新建一個MyCoroutineProcess.php
namespace process;
use Workbunny\WebmanCoroutine\CoroutineWorkerInterface;
use Workbunny\WebmanCoroutine\CoroutineWorkerMethods;
class MyCoroutineProcess extends MyProcess implements CoroutineWorkerInterface {
// 引入?yún)f(xié)程代理方法
use CoroutineWorkerMethods;
}
此時的MyCoroutineProcess
將擁有協(xié)程化的onWorkerStart()
,將新建的MyCoroutineProcess
添加到 webman 的自定義進程配置config/process.php
中啟動即可
假設(shè)我們已經(jīng)存在一個自定義服務(wù)類,如MyServer.php
namespace process;
class MyServer {
public function onMessage($connection, $data) {
// 具體業(yè)務(wù)邏輯
}
// ...
}
在webman/workerman
環(huán)境中,onMessage()
是一個具備監(jiān)聽能力的進程所必不可少的方法,假設(shè)我們想要將它協(xié)程化,在不改動MyServer
的情況下,只需要新建一個MyCoroutineServer.php
namespace process;
use Workbunny\WebmanCoroutine\CoroutineServerInterface;
use Workbunny\WebmanCoroutine\CoroutineServerMethods;
class MyCoroutineServer extends MyServer implements CoroutineServerInterface {
// 引入?yún)f(xié)程代理方法
use CoroutineServerMethods;
}
此時的MyCoroutineServer
將擁有協(xié)程化的onMessage()
,將新建的MyCoroutineServer
添加到 webman 的自定義進程配置config/process.php
中啟動即可
Swow 的協(xié)程是面向?qū)ο蟮?,所以我們可以這樣創(chuàng)建一個待運行的協(xié)程
use Swow\Coroutine;
$coroutine = new Coroutine(static function (): void {
echo "Hello 開源技術(shù)小棧\n";
});
這樣創(chuàng)建出來的協(xié)程并不會被運行,而是只進行了內(nèi)存的申請。
通過 var_dump
打印協(xié)程對象,我們又可以看到這樣的輸出:
var_dump($coroutine);
打印輸出
class Swow\Coroutine#240 (4) {
public $id =>
int(12)
public $state =>
string(7) "waiting"
public $switches =>
int(0)
public $elapsed =>
string(3) "0ms"
}
從輸出我們可以得到一些協(xié)程狀態(tài)的信息,如:協(xié)程的 id
是12
,狀態(tài)是等待中
,切換次數(shù)是0
,運行了0
毫秒(即沒有運行)。
通過 resume()
方法,我們可以喚醒這個協(xié)程:
$coroutine->resume();
協(xié)程中的PHP代碼被執(zhí)行,于是我們就看到了下述信息:
Hello 開源技術(shù)小棧
這時候我們再通過 var_dump($coroutine);
去打印協(xié)程的狀態(tài),我們得到以下內(nèi)容:
class Swow\Coroutine#240 (4) {
public $id =>
int(12)
public $state =>
string(4) "dead"
public $switches =>
int(1)
public $elapsed =>
string(3) "0ms"
}
可以看到協(xié)程已經(jīng)運行完了所有的代碼并進入dead
狀態(tài),共經(jīng)歷一次協(xié)程切換。
?? 版權(quán)聲明
作者:Tinywan
原文:https://mp.weixin.qq.com/s/SoyKa9zplMybCJ_n7YlW0Q
本文版權(quán)歸作者和workerman官方共有。歡迎轉(zhuǎn)載,但必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
歡迎關(guān)注 [開源技術(shù)小棧] 微信公眾號,一起進步!掃描下方二維碼即可
非常棒的文章!能介紹一下如何協(xié)程CURD就好了~
另外微信公眾號的文章,用手機上所有瀏覽器都打不開(卡退),不知是不是圖片太多的緣故
windows下測試了一番,會報錯(訪問頁面時):
Error: Class "Swow\Coroutine" not found in D:\Documents\Desktop\testWebman\webman-coroutine\app\controller\IndexController.php:31
Stack trace:
#0 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\webman-framework\src\App.php(322): app\controller\IndexController->test1(Object(support\Request))
#1 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\webman-framework\src\App.php(169): Webman\App::Webman\{closure}(Object(support\Request))
#2 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\workerman\Connection\TcpConnection.php(646): Webman\App->onMessage(Object(Workerman\Connection\TcpConnection), Object(support\Request))
#3 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\workerman\Events\Select.php(311): Workerman\Connection\TcpConnection->baseRead(Resource id #165)
#4 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\workerman\Worker.php(1488): Workerman\Events\Select->loop()
#5 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\workerman\Worker.php(1405): Workerman\Worker::forkWorkersForWindows()
#6 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\workerman\Worker.php(560): Workerman\Worker::forkWorkers()
#7 D:\Documents\Desktop\testWebman\webman-coroutine\vendor\workerman\webman-framework\src\support\App.php(131): Workerman\Worker::runAll()
#8 D:\Documents\Desktop\testWebman\webman-coroutine\start.php(4): support\App::run()
#9 {main}
在《webman如何使用swow事件驅(qū)動和協(xié)程?》文章中測試,仍然是這個報錯(啟動webman時);
我已經(jīng)嚴格按照教程的步驟做的,php為8.3,swow的官方編譯好的dll也放在ext目錄下,64位 和 nts 都一致,啟動命令:php -d extension=swow windows.php,config.php配置'event_loop' => \Workbunny\WebmanCoroutine\event_loop()(此文章)'event_loop' => \Workerman\Events\Swow::class(后面文章)。