???? 感謝兔子大佬
chaz6chez
的協(xié)程插件 http://wtbis.cn/plugin/167
???? webman-coroutine 是一個(gè) webman 開(kāi)發(fā)框架生態(tài)下的協(xié)程基建支撐插件。
Github:https://github.com/workbunny/webman-coroutine
主要實(shí)現(xiàn)以下功能:
workerman 4.x
的 swow 協(xié)程驅(qū)動(dòng)能力,兼容workerman 5.x
版本自帶的swow
協(xié)程驅(qū)動(dòng);workerman 4.x
的 swoole 協(xié)程驅(qū)動(dòng)能力,兼容workerman 5.x
版本自帶的swoole
協(xié)程驅(qū)動(dòng);coroutine web server
用于實(shí)現(xiàn)具備協(xié)程能力的 web 框架基建revolt
等workerman 4.x/5.x
驅(qū)動(dòng)下的 webman 框架無(wú)法完整使用swoole
的協(xié)程能力,所以使用CoroutineWebServer
來(lái)替代webman
自帶的webServer
workerman 4.x
下還未有官方支持的swow
協(xié)程驅(qū)動(dòng),本插件提供SwowEvent
事件驅(qū)動(dòng)支撐workerman 4.x
下的協(xié)程能力event-loop
等操作相較于普通開(kāi)發(fā)會(huì)存在一定的心智負(fù)擔(dān),所以本插件提供了event_loop()
函數(shù),用于根據(jù)當(dāng)前環(huán)境自動(dòng)選擇合適的事件驅(qū)動(dòng)通過(guò)
composer
安裝
composer require workbunny/webman-coroutine
注: 目前在開(kāi)發(fā)階段,體驗(yàn)請(qǐng)使用
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
默認(rèn)端口channel_size : (int)
協(xié)程webServer
默認(rèn)每個(gè)stream
的channel
容量./vendor/bin/swow-builder
安裝swow
拓展,注意請(qǐng)關(guān)閉swoole
環(huán)境config/server.php
中'event_loop' => \Workbunny\WebmanCoroutine\event_loop()
,event_loop()
函數(shù)會(huì)根據(jù)當(dāng)前環(huán)境自行判斷當(dāng)前的 workerman 版本,自動(dòng)選擇合適的事件驅(qū)動(dòng)
swow
拓展時(shí),workerman 4.x
下使用SwowEvent
事件驅(qū)動(dòng)swow
拓展時(shí),workerman 5.x
下使用workerman
自帶的Swow
事件驅(qū)動(dòng)swow
時(shí),使用workerman
自帶的Event
事件驅(qū)動(dòng)php -d extension=swow webman start
啟動(dòng)CoroutineWebServer
注:
CoroutineWebServer
可以在config/plugin/workbunny/webman-coroutine/app.php
中通過(guò)enable=false
關(guān)閉啟動(dòng)
通過(guò)以下命令啟動(dòng)
php -d extension=swow webman start
啟動(dòng)輸出
# 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ù)會(huì)根據(jù)當(dāng)前環(huán)境自行判斷當(dāng)前的 workerman 版本,自動(dòng)選擇合適的事件驅(qū)動(dòng)
php -d extension=swoole webman start
啟動(dòng)config/plugin/workbunny/webman-coroutine/process.php
啟動(dòng)的 CoroutineWebServer 可以用于協(xié)程環(huán)境開(kāi)發(fā),原服務(wù)還是 BIO 模式composer require cclilshy/p-ripple-drive
安裝 ripple 驅(qū)動(dòng)插件config/server.php
配置
'event_loop' => \Workbunny\WebmanCoroutine\event_loop()
自動(dòng)判斷,請(qǐng)勿開(kāi)啟 swow、swoole,'event_loop' => \Workbunny\WebmanCoroutine\Factory::RIPPLE_FIBER
手動(dòng)指定php webman start
啟動(dòng)注:該環(huán)境協(xié)程依賴(lài)
php-fiber
,并沒(méi)有自動(dòng)hook
系統(tǒng)的阻塞函數(shù),但支持所有支持php-fiber
的插件
Workbunny\WebmanCoroutine\Handlers\HandlerInterface
接口,實(shí)現(xiàn)自定義協(xié)程處理邏輯Workbunny\WebmanCoroutine\Factory::register(HandlerInterface $handler)
注冊(cè)你的協(xié)程處理器config/server.php
中'event_loop' => {你的事件循環(huán)類(lèi)}
CoroutineWebServer
接受處理協(xié)程請(qǐng)求注:
\Workbunny\WebmanCoroutine\event_loop()
自動(dòng)判斷加載順序按\Workbunny\WebmanCoroutine\Factory::$_handlers
的順序執(zhí)行available()
擇先注:因?yàn)?code>eventLoopClass與
HandlerClass
是一一對(duì)應(yīng)的,所以建議不管是否存在相同的事件循環(huán)或者相同的處理器都需要繼承后重命名
webman-coroutine
提供了用于讓自己的自定義服務(wù)/進(jìn)程協(xié)程化的基礎(chǔ)工具
注:考慮到 webman 框架默認(rèn)不會(huì)啟用注解代理,所以這里沒(méi)有使用注解代理來(lái)處理協(xié)程化代理
假設(shè)我們已經(jīng)存在一個(gè)自定義服務(wù)類(lèi),如MyProcess.php
namespace process;
class MyProcess {
public function onWorkerStart() {
// 具體業(yè)務(wù)邏輯
}
// ...
}
在webman/workerman
環(huán)境中,onWorkerStart()
是一個(gè) worker 進(jìn)程所必不可少的方法,
假設(shè)我們想要將它協(xié)程化,在不改動(dòng)MyProcess
的情況下,只需要新建一個(gè)MyCoroutineProcess.php
namespace process;
use Workbunny\WebmanCoroutine\CoroutineWorkerInterface;
use Workbunny\WebmanCoroutine\CoroutineWorkerMethods;
class MyCoroutineProcess extends MyProcess implements CoroutineWorkerInterface {
// 引入?yún)f(xié)程代理方法
use CoroutineWorkerMethods;
}
此時(shí)的MyCoroutineProcess
將擁有協(xié)程化的onWorkerStart()
,將新建的MyCoroutineProcess
添加到 webman 的自定義進(jìn)程配置config/process.php
中啟動(dòng)即可
假設(shè)我們已經(jīng)存在一個(gè)自定義服務(wù)類(lèi),如MyServer.php
namespace process;
class MyServer {
public function onMessage($connection, $data) {
// 具體業(yè)務(wù)邏輯
}
// ...
}
在webman/workerman
環(huán)境中,onMessage()
是一個(gè)具備監(jiān)聽(tīng)能力的進(jìn)程所必不可少的方法,假設(shè)我們想要將它協(xié)程化,在不改動(dòng)MyServer
的情況下,只需要新建一個(gè)MyCoroutineServer.php
namespace process;
use Workbunny\WebmanCoroutine\CoroutineServerInterface;
use Workbunny\WebmanCoroutine\CoroutineServerMethods;
class MyCoroutineServer extends MyServer implements CoroutineServerInterface {
// 引入?yún)f(xié)程代理方法
use CoroutineServerMethods;
}
此時(shí)的MyCoroutineServer
將擁有協(xié)程化的onMessage()
,將新建的MyCoroutineServer
添加到 webman 的自定義進(jìn)程配置config/process.php
中啟動(dòng)即可
Swow 的協(xié)程是面向?qū)ο蟮?,所以我們可以這樣創(chuàng)建一個(gè)待運(yùn)行的協(xié)程
use Swow\Coroutine;
$coroutine = new Coroutine(static function (): void {
echo "Hello 開(kāi)源技術(shù)小棧\n";
});
這樣創(chuàng)建出來(lái)的協(xié)程并不會(huì)被運(yùn)行,而是只進(jìn)行了內(nèi)存的申請(qǐng)。
通過(guò) var_dump
打印協(xié)程對(duì)象,我們又可以看到這樣的輸出:
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
,運(yùn)行了0
毫秒(即沒(méi)有運(yùn)行)。
通過(guò) resume()
方法,我們可以喚醒這個(gè)協(xié)程:
$coroutine->resume();
協(xié)程中的PHP代碼被執(zhí)行,于是我們就看到了下述信息:
Hello 開(kāi)源技術(shù)小棧
這時(shí)候我們?cè)偻ㄟ^(guò) 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)運(yùn)行完了所有的代碼并進(jìn)入dead
狀態(tài),共經(jīng)歷一次協(xié)程切換。
?? 版權(quán)聲明
作者:Tinywan
原文:https://mp.weixin.qq.com/s/SoyKa9zplMybCJ_n7YlW0Q
本文版權(quán)歸作者和workerman官方共有。歡迎轉(zhuǎn)載,但必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。
歡迎關(guān)注 [開(kāi)源技術(shù)小棧] 微信公眾號(hào),一起進(jìn)步!掃描下方二維碼即可
非常棒的文章!能介紹一下如何協(xié)程CURD就好了~
另外微信公眾號(hào)的文章,用手機(jī)上所有瀏覽器都打不開(kāi)(卡退),不知是不是圖片太多的緣故
從FPM轉(zhuǎn)到CLI,覺(jué)得性能已經(jīng)很強(qiáng)了,現(xiàn)在又加上協(xié)程,這是要起飛呀。
windows下測(cè)試了一番,會(huì)報(bào)錯(cuò)(訪問(wèn)頁(yè)面時(shí)):
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ū)動(dòng)和協(xié)程?》文章中測(cè)試,仍然是這個(gè)報(bào)錯(cuò)(啟動(dòng)webman時(shí));
我已經(jīng)嚴(yán)格按照教程的步驟做的,php為8.3,swow的官方編譯好的dll也放在ext目錄下,64位 和 nts 都一致,啟動(dòng)命令:php -d extension=swow windows.php,config.php配置'event_loop' => \Workbunny\WebmanCoroutine\event_loop()(此文章)'event_loop' => \Workerman\Events\Swow::class(后面文章)。