Swoole:PHP 協程框架
Swoole 使 PHP 開發人員可以編寫高性能高并發的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服務,讓 PHP 不再局限于 Web 領域。Swoole4 協程的成熟將 PHP 帶入了前所未有的時期, 為性能的提升提供了獨一無二的可能性。Swoole 可以廣泛應用于互聯網、移動通信、云計算、 網絡游戲、物聯網(IOT)、車聯網、智能家居等領域。使用 PHP + Swoole 可以使企業 IT 研發團隊的效率大大提升,更加專注于開發創新產品。
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function() {
sleep(1);
});
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function() {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$result = $redis->keys('*');
var_dump($result);
});
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://httpbin.org/get');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
var_dump($result);
});
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function () {
go(function () {
$pdo = new PDO('mysql:host=10.66.110.163;dbname=coding_test;charset=utf8', 'coding_test', 'coding_test');
$statement = $pdo->prepare('SELECT * FROM `coding_test`');
$statement->execute();
var_dump($statement->fetchAll());
});
go(function () {
$mysqli = new mysqli('10.66.110.163', 'coding_test', 'coding_test', 'coding_test');
$statement = $mysqli->prepare('SELECT `id` FROM `coding_test`');
$statement->bind_result($id);
$statement->execute();
$statement->fetch();
var_dump($id);
});
});
use Swoole\Coroutine;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function() {
$result = [];
Coroutine::join([
go(function () use (&$result) {
$result['baidu'] = file_get_contents("https://www.baidu.com/");
}),
go(function () use (&$result) {
$result['taobao'] = file_get_contents("https://www.taobao.com/");
})
]);
echo "all done\n";
});
$http = new Swoole\Http\Server('127.0.0.1', 9501);
$http->on('start', function ($server) {
echo "Swoole http server is started at http://127.0.0.1:9501\n";
});
$http->on('request', function ($request, $response) {
$response->header('Content-Type', 'text/plain');
$response->end('Hello World');
});
$http->start();
$server = new Swoole\Server('127.0.0.1', 9503);
$server->on('start', function ($server) {
echo "TCP Server is started at tcp://127.0.0.1:9503\n";
});
$server->on('connect', function ($server, $fd){
echo "connection open: {$fd}\n";
});
$server->on('receive', function ($server, $fd, $reactor_id, $data) {
$server->send($fd, "Swoole: {$data}");
});
$server->on('close', function ($server, $fd) {
echo "connection close: {$fd}\n";
});
$server->start();
$server = new Swoole\Server('127.0.0.1', 9504, SWOOLE_PROCESS, SWOOLE_SOCK_UDP);
$server->on('start', function ($server) {
echo "UDP Server is started at udp://127.0.0.1:9504\n";
});
$server->on('packet', function ($server, $data, $clientInfo) {
$server->sendTo($clientInfo['address'], $clientInfo['port'], "Server:{$data}");
});
$server->start();
$server = new Swoole\Websocket\Server('127.0.0.1', 9502);
$server->on('start', function ($server) {
echo "Websocket Server is started at ws://127.0.0.1:9502\n";
});
$server->on('open', function($server, $req) {
echo "connection open: {$req->fd}\n";
});
$server->on('message', function($server, $frame) {
echo "received message: {$frame->data}\n";
$server->push($frame->fd, json_encode(['hello', 'world']));
});
$server->on('close', function($server, $fd) {
echo "connection close: {$fd}\n";
});
$server->start();
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function() {
$id = go(function(){
$id = Co::getUid();
echo "start coro $id\n";
Co::suspend($id);
echo "resume coro $id @1\n";
Co::suspend($id);
echo "resume coro $id @2\n";
});
echo "start to resume $id @1\n";
Co::resume($id);
echo "start to resume $id @2\n";
Co::resume($id);
echo "main\n";
});
use Swoole\Coroutine;
use Swoole\Coroutine\Channel;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function(){
$channel = new Channel(1);
go(function () use ($channel) {
for($i = 0; $i < 10; $i++) {
Coroutine::sleep(1.0);
$channel->push(['rand' => rand(1000, 9999), 'index' => $i]);
echo "{$i}\n";
}
});
go(function () use ($channel) {
while(true) {
$data = $channel->pop(2.0);
if ($data) {
var_dump($data);
} else {
assert($channel->errCode === SWOOLE_CHANNEL_TIMEOUT);
break;
}
}
});
});
use Swoole\Coroutine\Socket;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
run(function() {
go(function () {
$socket = new Socket(AF_INET, SOCK_DGRAM, 0);
$socket->bind('127.0.0.1', 9503);
$client_map = [];
for ($c = 128; $c--;) {
for ($n = 0; $n < 100; $n++) {
$recv = $socket->recvfrom($peer);
$client_uid = "{$peer['address']}:{$peer['port']}";
$id = $client_map[$client_uid] = ($client_map[$client_uid] ?? -1) + 1;
assert($recv === "Client: Hello #{$id}!");
$socket->sendto($peer['address'], $peer['port'], "Server: Hello #{$id}!");
}
}
$socket->close();
});
for ($c = 128; $c--;) {
go(function () {
$fp = stream_socket_client('udp://127.0.0.1:9503', $errno, $errstr, 1);
if (!$fp) {
echo "{$errstr} ({$errno})\n";
return;
}
for ($n = 0; $n < 100; $n++) {
fwrite($fp, "Client: Hello #{$n}!");
$recv = fread($fp, 1024);
list($address, $port) = explode(':', (stream_socket_get_name($fp, true)));
assert($address === '127.0.0.1' && (int)$port === 9503);
assert($recv === "Server: Hello #{$n}!");
}
fclose($fp);
});
}
echo 'Done', PHP_EOL;
});
use function Swoole\Coroutine\run;
run(function(){
$fp1 = stream_socket_client('tcp://www.baidu.com:80', $errno, $errstr, 30);
$fp2 = stream_socket_client('tcp://www.qq.com:80', $errno, $errstr, 30);
if (!$fp1) {
echo "$errstr ($errno) \n";
} else {
fwrite($fp1, "GET / HTTP/1.0\r\nHost: www.baidu.com\r\nUser-Agent: curl/7.58.0\r\nAccept: */*\r\n\r\n");
$r_array = [$fp1, $fp2];
$w_array = $e_array = null;
$n = stream_select($r_array, $w_array, $e_array, 10);
$html = '';
while (!feof($fp1)) {
$html .= fgets($fp1, 1024);
}
fclose($fp1);
echo strlen($html);
}
});
$server = new Swoole\Server('127.0.0.1', 9503);
$server->set(['task_worker_num' => 4]);
$server->on('start', function ($server) {
echo "TCP Server is started at tcp://127.0.0.1:9503\n";
});
$server->on('receive', function($server, $fd, $reactor_id, $data) {
$task_id = $server->task('Async');
$server->send($fd, "Dispatch AsyncTask: [id={$task_id}]\n");
});
$server->on('task', function ($server, $task_id, $reactor_id, $data) {
echo "New AsyncTask[id={$task_id}]\n";
$server->finish("{$data} -> OK");
});
$server->on('finish', function ($server, $task_id, $data) {
echo "AsyncTask[{$task_id}] finished: {$data}\n";
});
$server->start();
開源、高性能、生產力
如果您有基于 Swoole 的優秀項目希望展示在官網,請掃描微信二維碼聯系我們
店滴云開源框架
店滴云是針對多商戶業務開發的一套管理cms,支持多運營主體,單運營主體運營開發。基于世界上最好的語言php和yii開發,深度集成swoole,滿足需要http/tcp/mqtt等多種協議的業務場景,官方提供智能門鎖,智能開關成熟的解決方案。采用最新的vue開發技術作為中后臺管理,多終端開發框架uniapp打造,旨在讓開發更有趣味和成就感,希望可以助力更多的中小企業實現業績增長,技術創新和持續發展。官方依賴于店滴云先后開發了疫情大數據監測,企業外呼,im客服,多商戶分銷,外賣點餐,政企黨建等系統。PHP 微服務(Micro Service)
Hyperf 是基于 Swoole 4.4+ 實現的高性能、高靈活性的 PHP 協程框架,內置協程服務器及大量常用的組件,性能較傳統基于 PHP-FPM 的框架有質的提升,提供超高性能的同時,也保持著極其靈活的可擴展性,標準組件均基于 PSR 標準實現,基于強大的依賴注入設計,保證了絕大部分組件或類都是可替換與可復用的基于 Swoole 的多進程隊列系統
基于 Swoole 的多進程隊列系統,Manager 進程管理子進程,Master 進程監聽隊列分發任務,Worker 進程執行任務, 多進程、低延時(最低毫秒級)、高可用、低資源占用、可多服務器分布式部署。可與 Laravel、ThinkPHP 等框架配合使用。默認 Redis 驅動,原子性操作,支持延時投遞、錯誤重試、自定義超時,支持后臺守護運行,無需其余進程管理工具。提供多種命令,方便管理及查詢進程狀態、任務狀態。ShopXO開源商城
ShopXO企業級免費開源電商系統!求實進取、創新專注、自主研發、國內領先企業級電商系統解決方案。遵循MIT開源協議發布,無需授權、可商用、可二次開發、滿足99%的電商運營需求。支持PC+H5、支付寶小程序、微信小程序、百度小程序、頭條&抖音小程序、QQ小程序、APP等...支持多倉庫、多商戶、線下門店模式運營(組件插件化、即插即用),可視化DIY拖拽裝修。多端統一客服系統采用Swoole高性能WebSocket構建。LaravelS
LaravelS 是 Swoole 和 Laravel/Lumen 之間開箱即用的適配器,內置 HTTP/WebSocket Server,支持 TCP/UDP Server、自定義進程、異步的事件監聽、異步任務、毫秒級定時任務、平滑Reload等特性,讓 Laravel 如虎添翼。xlswriter
xlswriter是一個 PHP C 擴展,支持 Swoole 協程環境,可用于在 Excel 2007+ XLSX 文件中讀取數據,插入多個工作表,寫入文本、數字、公式、日期、圖表、圖片和超鏈接。物聯網(IOT)解決方案
MQTT 是一個客戶端服務端架構的發布 / 訂閱模式的消息傳輸協議。它的設計思想是輕巧、開放、簡單、規范,易于實現。這些特點使得它對很多場景來說都是很好的選擇,特別是對于受限的環境如機器與機器的通信(M2M)以及物聯網環境(IoT)。可以使用 Swoole 作為 MQTT 服務端或客戶端,實現一套完整物聯網(IOT)解決方案ZooKeeper
基于 Swoole 協程的PHP ZooKeeper客戶端HyperfCMS
HyperfCMS 是基于 Swoole+Hyperf 框架前后端分離架構的一套開源且完美的建站系統,擁有簡單大氣設計、友好的交互體驗、清晰明了的代碼規范。組件化的封裝應用,編寫復雜的管理應用,效率是質的提升、時間成倍縮短,人員可以減半,事半功倍。可以提供定制化服務!HCMS
Hcms 是一個基于 Hyperf 框架的項目開發管理系統 , 在Hyperf超高速且靈活的特性加持下,構建一個快速開發、模塊復用的項目開發管理系統。PaySDK
PHP 集成支付 SDK ,集成了支付寶、微信支付的支付接口和其它相關接口的操作。支持 php-fpm 和 Swoole,所有框架通用。Swoole Worker
Swoole Worker是基于Swoole4開發的一款分布式長連接開發框架。常駐內存,協程,高性能高并發;分布式部署,橫向擴容,使得能支持龐大的連接數;無感知安全重啟,無縫升級代碼;接口豐富,支持單個發送,分組發送,群發廣播等接口。ThinkCMF
ThinkCMF 是一款基于 ThinkPHP+Mysql 開發的 CMS,完美支持 Swoole,框架自身提供基礎的管理功能,而開發者可以根據自身的需求以應用的形式進行擴展。每個應用都能獨立的完成自己的任務,也可通過系統調用其他應用進行協同工作。在這種運行機制下,開發商場應用的用戶無需關心開發 SNS 應用時如何工作的,但他們之間又可通過系統本身進行協調,大大的降低了開發成本和溝通成本Yasd
Yasd 是一個 Swoole 調試器,類似 Xdebug,完美支持協程,支持斷點調試、單步追蹤、watch 變量Markdown文檔系統
軟擎文檔系統是基于 Swoole + Rangine 框架開發的開源版 MarkDown 文檔管理系統,不同于 docsify.js 等前端文檔系統,本文檔系統是偏后端的文檔系統,對于廣大PHPer來說更加友好。支持多用戶協同操作,管理員審核發布等功能。 讓您的工作更高效,更智慧。魔獸世界
魔獸模擬游戲服務器,項目采用 PHP 開發,TCP 長連接基于 Swoole,支持鑒權,角色的創建,地圖的加載,NPC 和生物的構建及各種眼花繚亂的物品和技能等等斗地主
基于 Swoole + Hyperf 框架開發 demo 級的斗地主游戲,實現斗地主游戲服務端邏輯,并采用原生 js 和 WebSocket 實現簡單的客戶端打牌邏輯,可以做到簡單的玩斗地主游戲MyCMS
MyCMS 是一款基于 Laravel 開發開源免費的商城博客 CMS 建站系統,通過集成 Swoole 大幅度提升系統的性能,功能和性能兼得分布式定時任務 (Swoole Crontab)
基于 Swoole 的定時器程序,支持秒級處理,完全兼容 crontab 語法,且支持秒的配置,可使用數組規定好精確操作時間,Web 界面管理,增刪改查任務,完整的權限控制電商系統 CRMEB Pro
CRMEB Pro采用Tp6 + Swoole+redis高性能框架開發;是一款高性能、高并發、高可用的私域客戶關系管理(CRM)+營銷電商(EB)系統;助力品牌商家實現公域引流轉化私域沉淀,全渠道智能化經營。系統基于異步事件驅動和協程的并行網絡通信引擎,充分利用了底層的epoll / kqueue實現網絡事件請求處理;通過 Swoole協程異步處理數據,徹底解決了PHP高并發處理問題;通過集群部署,進一步提升系統性能。是品牌電商系統的第一選擇!MoChat
MoChat - 基于 Hyperf 框架的國內首款完全開源的 PHP 企業微信管理系統Ain't Queue 異步隊列
Ain't Queue 借助 Swoole 提供的便捷多進程 API 和 CSP 編程能力實現了主進程+監控進程+多工作進程的進程模型,并且提供了各類事件自定義注冊的能力(隊列監控、快照記錄、任務中間件等)。默認使用 Redis 驅動,全原子操作,可延時可重試,自帶漂亮的儀表盤,穩定可靠,已經在公司生產環境使用。Mysql Proxy(Mysql中間件)
一個基于 MySQL 協議,Swoole 開發的 MySQL 數據庫連接池,支持讀寫分離支持數據庫連接池,能夠有效解決 PHP 帶來的數據庫連接瓶頸,支持 SQL92 標準,采用協程調度,遵守 MySQL 原生協議,跨語言,跨平臺的通用中間件代理,支持 MySQL 事務,完美兼容 MySQL5.5 - 8.0實時視頻語音 (Webrtc)
基于 Swoole4 高性能協程的 demo 級實時視頻和語音通話方案,采用 webrtc 協議,并已經做好 p2p 打洞,中繼服務器,演示地址:https://webrtc.dingjw.com/room.php?cid=2Swoole 特性
Swoole 使用 C/C++ 語言編寫,提供了 PHP 語言的異步多線程服務器、異步 TCP/UDP 網絡客戶端、異步 MySQL、異步 Redis、數據庫連接池、AsyncTask、消息隊列、毫秒定時器、異步文件讀寫、異步 DNS 查詢。 Swoole 內置了 Http/WebSocket 服務器端/客戶端、Http2.0 服務器端。
除了異步 IO 的支持之外,Swoole 為 PHP 多進程的模式設計了多個并發數據結構和 IPC 通信機制,可以大大 簡化多進程并發編程的工作。其中包括了原子計數器、Table、Channel、Lock、進程間通信 IPC 等豐富的功能特性。
Swoole4.0 支持了類似 Go 語言的協程,可以使用完全同步的代碼實現異步程序。PHP 代碼無需額外增加任何 關鍵詞,底層自動進行協程調度,實現異步 IO。