内容简介:上一篇文章本篇文章分為以下三個章節 :reactPHP 官網寫這一段話 :
上一篇文章 PHP 的 Web 運行原理 ( 2 ) - 非阻塞 I/O 之 Reactor 模式
我們理解到實現非阻塞 I/O 的 reactor 模式以後,接下來本篇文章我們將來要說明,在 php 中的 reactor 實現 reactPHP
。
本篇文章分為以下三個章節 :
- reactPHP 基本概念
- reactPHP 非阻塞 I/O 實現
- reactPHP 使用時注意事項
reactPHP 基本概念
reactPHP 官網寫這一段話 :
Event-driven, non-blocking I/O with PHP
它是一個用 php 所寫的 libaray,可以幫助我們做以下的事情 :
- 可以建立一個非阻塞 I/O 的網路服務。
- 可以建立一個定時排程服務。
http server 的範例
下面就是官網首頁的範例,我們可以用它簡單的建立一個非阻塞 I/O 的 http server,就如同 nodejs 一樣。
$loop = React\EventLoop\Factory::create(); $server = new React\Http\Server(function (Psr\Http\Message\ServerRequestInterface $request) { return new React\Http\Response( 200, array('Content-Type' => 'text/plain'), "Hello World!\n" ); }); $socket = new React\Socket\Server(8080, $loop); $server->listen($socket); echo "Server running at http://127.0.0.1:8080\n"; $loop->run();
排程服務的範例
$loop = React\EventLoop\Factory::create(); // 5 秒後執行 $loop->addPeriodicTimer(5, function () { echo "Hi Mark"; }); $loop->run();
reactPHP 非阻塞 I/O 實現
那 reactPHP 它是如何實現非阻塞 I/O 模式呢 ?
它就是如我們標題所說,它使用 reactor 模式
來實現非阻塞 I/O 模式,並且它與 nodejs 一樣使用 single process 的 reactor 模式。
備註: 為什麼 single process 可以做到非阻塞 I/O 請參考前一篇文章。
架構圖如下,就是一個 reactor 機制,其中它的 process 裡面就有所謂的 I/O 多路復用技術。
假設我們有一段程式碼要執行,那麼它的運行原理流程如下 :
- 建立 event loop。
- 將 addPeriodicTimer 5 秒後要執行的事件丟到 queue 中。
- 執行 event loop。(也就是開始跑無窮迴圈)
- event loop 在 5 秒時,發現有個要執行的任務 callback function
- 執行 echo "Hi Mark"。
- 將立 http 請求,並將它丟到 queue 中。
- event loop 當發現 I/O 操作有回復時,則執行 callback function
- echo $chunk。
(1) $loop = React\EventLoop\Factory::create(); $client = new React\HttpClient\Client($loop); // 5 秒後執行 (2) $loop->addPeriodicTimer(5, function () { (4) (5) echo "Hi Mark"; (6) $request = $client->request('GET', 'https://github.com/'); $request->on('response', function ($response) { $response->on('data', function ($chunk) { (7) echo $chunk; }); $response->on('end', function() { echo 'DONE'; }); }); (3) $loop->run();
使用時注意事項
reactPHP 理論上是 php 版的 nodejs 但實際使用要注意,不是。
假設我們使用 reactPHP 然後來寫一個 http server。
然後當 server 收到一個請求時,它會再使用 file_get_contents
這個方法去打某個 api,這 api 需要一分鐘左右才能回應。
<?php require __DIR__ . '/vendor/autoload.php'; $loop = React\EventLoop\Factory::create(); $server = new React\Http\Server(function (Psr\Http\Message\ServerRequestInterface $request) use ($client) { // ---------------------------------------------------- var_dump('wait...'); // 假設這一段要執行一分鐘。 $response = file_get_contents('http://127.0.0.1:3000'); var_dump('done !...'); // ---------------------------------------------------- return new React\Http\Response( 200, array('Content-Type' => 'text/plain'), "Hello World!\n" ); }); $socket = new React\Socket\Server(8080, $loop); $server->listen($socket); echo "Server running at http://127.0.0.1:8080\n"; $loop->run();
假設往這個使用 reactPHP 寫的 http server,發送兩次請求,上面的 wait 會看到幾次呢 ?
答案是 : 1 次
因為第一次請求時,就將整個 process 給阻塞住了,所以第二個請求完全無法處理。
它不是說它有提供非阻塞 I/O 的功能嗎 ?
嗯對的,它有提供,但是前提假設為,你要使用它。
你在寫 nodejs 時,上面這個相似範例 process 就不會被阻塞住,因為它在給 v8 處理完 binding c++ 階段時,會將所有的 I/O 操作執行完並且丟到 event loop 機制中,所以在 nodejs 操作 I/O 時,你什麼都沒做,就會是非阻塞的 I/O 操作。
而在 reactPHP 中,你要自已處理又或是使用它所提供的 http client 才能讓變成非阻塞 I/O 的操作。如下範例。
<?php require __DIR__ . '/vendor/autoload.php'; $loop = React\EventLoop\Factory::create(); $client = new React\HttpClient\Client($loop); $server = new React\Http\Server(function (Psr\Http\Message\ServerRequestInterface $request) use ($client) { // ---------------------------------------------------- var_dump('wait...'); $request = $client->request('GET', 'http://127.0.0.1:3000'); $request->on('response', function ($response) { $response->on('data', function ($chunk) { echo $chunk; }); $response->on('end', function() { echo 'DONE'; }); var_dump('done !...'); // ---------------------------------------------------- return new React\Http\Response( 200, array('Content-Type' => 'text/plain'), "Hello World!\n" ); }); $socket = new React\Socket\Server(8080, $loop); $server->listen($socket); echo "Server running at http://127.0.0.1:8080\n"; $loop->run();
結論
本篇文章中我們學習了幾個重點:
reactPHP 基本概念
就是這段話。
Event-driven, non-blocking I/O with PHP
reactPHP 非阻塞 I/O 實現
它使用 single process 的 reactor 模式
來實現。
使用時注意事項
在使用它時注意,你要確保你所有的 I/O 操作,都有丟到 event loop 中,否則,它仍然是阻塞 I/O 操作,就如同範例一樣。
參考資料
以上所述就是小编给大家介绍的《PHP 的 Web 運行原理 ( 3 ) - PHP Reactor 實現之 reactPHP》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- java反射原理, 注解原理
- Webpack 原理(二):加载原理
- Docker原理之 - CGroup实现原理
- 【Vue原理】响应式原理 - 白话版
- Docker实现原理之 - OverlayFS实现原理
- UAV MOF工作原理之Agent注入机制原理
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Mastering JavaServer Faces
Bill Dudney、Jonathan Lehr、Bill Willis、LeRoy Mattingly / Wiley / 2004-6-7 / USD 40.00
Harness the power of JavaServer Faces to create your own server-side user interfaces for the Web This innovative book arms you with the tools to utilize JavaServer Faces (JSF), a new standard that wi......一起来看看 《Mastering JavaServer Faces》 这本书的介绍吧!