摘要:有研究過框架的同學就會發(fā)現(xiàn),其實最核心的,就是用了拓展加上拓展來實現(xiàn)其底層的網(wǎng)絡(luò)服務(wù)和多進程調(diào)度。我們在模式下,測試起五個進程主進程要等待回收我們,這樣就很簡單的實現(xiàn)了一個多進程的協(xié)程服務(wù)。
有研究過Workman框架的同學就會發(fā)現(xiàn),其實workman最核心的,就是用了php socket拓展加上pcntl拓展來實現(xiàn)其底層的網(wǎng)絡(luò)服務(wù)和多進程調(diào)度。那我們今天就來探討如何使用Swoole的CoroutineSocket模塊來實現(xiàn)自己的tcp服務(wù)。
我們先編寫一段小的測試代碼,test.php 代碼如下
$socket = new CoSocket(AF_INET, SOCK_STREAM, 0); $socket->bind("127.0.0.1", 9601); $socket->listen(128); go(function () use ($socket) { while(true) { $client = $socket->accept(-1); $data = $client->recv(64,10); var_dump("Recv:".$data); $client->sendAll("reply at ".time()); $client->close(); } });
我們執(zhí)行
php test.php
并新建一個cmd控制臺,用telnet模擬tcp客戶端,可以看到如下結(jié)果:
telnet 127.0.0.1 9601 Trying 127.0.0.1... Connected to localhost. Escape character is "^]". asd reply at 1559713416 Connection closed by foreign host
以上說明我們已經(jīng)成功建立了一個簡單的TCP服務(wù)器。而有細心的同學就會發(fā)現(xiàn),以上代碼如果我在recv后,有一些數(shù)據(jù)庫行為發(fā)生,那我該TCP服務(wù)器在同一時間就僅僅只能accept鏈接并處理一個鏈接的事情,并發(fā)能力接近于1。因此我們可以做一點小小的改進,如下:
$socket = new CoSocket(AF_INET, SOCK_STREAM, 0); $socket->bind("127.0.0.1", 9601); $socket->listen(128); go(function () use ($socket) { while(true) { $client = $socket->accept(-1); go(function () use ($client){ $data = $client->recv(64,10); var_dump("Recv:".$data); //模擬數(shù)據(jù)庫耗時,假定我們的數(shù)據(jù)庫也是用協(xié)程api co::sleep(1); $client->sendAll("reply at ".time()); $client->close(); }); } });
我們利用協(xié)程,把連接accept后的邏輯,全部放到另外一個子協(xié)程當中處理,讓我們的TCP服務(wù)器可以繼續(xù)accept連接,也就提高了我們的并發(fā)能力。然而,在實際的編程中,我們不可能做到完全的百分百協(xié)程API,而且我的機器也是多核心的處理器,那么此刻我如何盡可能的利用我的CPU呢?因此我們可以利用端口復用的特性和Swoole的Process來構(gòu)建一個多進程TCP協(xié)程服務(wù)器。
引入Process因為在本章節(jié)中,對Swoole Process的封裝不是我們關(guān)心的,因此我們這里直接使用EasySwoole封裝好的進程組件。
composer require easyswoole/component
實現(xiàn)我的Process Class,代碼如下
use CoSocket; use EasySwooleComponentProcessAbstractProcess; class Server extends AbstractProcess { protected function run($arg) { $socket = new Socket(AF_INET, SOCK_STREAM, 0); //關(guān)鍵在這里,允許復用 $socket->setOption(SOL_SOCKET,SO_REUSEPORT,true); $socket->setOption(SOL_SOCKET,SO_REUSEADDR,true); $socket->bind("127.0.0.1", 9601); $socket->listen(128); go(function () use ($socket) { while(true) { $client = $socket->accept(-1); go(function () use ($client){ $data = $client->recv(64,10); var_dump("Recv:".$data); //模擬數(shù)據(jù)庫耗時,假定我們的數(shù)據(jù)庫也是用協(xié)程api co::sleep(1); $client->sendAll("reply at ".time()); $client->close(); }); } }); } }
我們在以上代碼中,加入了允許端口復用的選項,否則在多進程模式下,會導致監(jiān)聽失敗。我們在cli模式下,測試起五個進程
for ($i = 1;$i < 5;$i++){ $p = new Server("TcpServer.{$i}"); $p->getProcess()->start(); } //主進程要等待回收 while($ret = SwooleProcess::wait()) { echo "PID={$ret["pid"]} "; }
我們,這樣就很簡單的實現(xiàn)了一個多進程的TCP協(xié)程服務(wù)。總而言之,Swoole 4.x的協(xié)程能力,還是很強大的,讓PHPer可以以最小的代價來實現(xiàn)一個高性能的TCP服務(wù),而不是需要去學習新的一門語言,若需要更多的完善代碼,可以參考http://easyswoole.com/ 這個框架的項目代碼,如果有喜歡的同學,可以隨意點個 star ,github地址 https://github.com/easy-swool...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31663.html
摘要:訪問安全問題為什么說有訪問安全問題呢傳統(tǒng)地,在的的環(huán)境中,很少有遇到所謂變量安全訪問問題。上下文管理器為了解決這個問題,我們引入?yún)f(xié)程上下文管理這樣的概念,由此來實現(xiàn)每個協(xié)程環(huán)境內(nèi)的數(shù)據(jù)隔離。 訪問安全問題 為什么說有訪問安全問題呢?傳統(tǒng)地,在php的的環(huán)境中,很少有Phper遇到所謂變量安全訪問問題。舉個例子,代碼大約如下: class db { protected stati...
摘要:然而盡管如此,很多人可能都沒有思考過,如何優(yōu)雅的寫出自己的物聯(lián)網(wǎng)服務(wù)器。 PHP不適合做物聯(lián)網(wǎng)服務(wù)端嗎? 在傳統(tǒng)的思維中,經(jīng)常會有人告訴你,php不適合用來做物聯(lián)網(wǎng)服務(wù)端,讓你換java,node,go等其他語言,是的,沒錯傳統(tǒng)意義上的php,確實很難做物聯(lián)網(wǎng)服務(wù)器,因為它實在太蹩腳了,當然,這也不是意味著徹底就不能做。舉個例子,當你想實現(xiàn)一個TCP服務(wù)器的時候,你可能需要寫出原理大約...
摘要:協(xié)程與信箱得益于,我們可以基于的協(xié)程與快速實現(xiàn)一個信箱模式調(diào)度。樣例代碼比如在一個聊天室中,我們可以定義一個房間模型。 什么是Actor? Actor對于PHPer來說,可能會比較陌生,寫過Java的同學會比較熟悉,Java一直都有線程的概念(雖然PHP有Pthread,但不普及),它是一種非共享內(nèi)存的并發(fā)模型,每個Actor內(nèi)的數(shù)據(jù)獨立存在,Actor之間通過消息傳遞的形式進行交互調(diào)...
摘要:年月日,在上海舉行的第六屆中國開發(fā)者大會上,騰訊開源項目首次全面發(fā)布版本,閱文集團高級開發(fā)工程師梁晨對如何通過構(gòu)建高性能框架做了經(jīng)驗分享。分享內(nèi)容作為騰訊開源的框架,在發(fā)布之后即受到開源領(lǐng)域的關(guān)注。閱文集團本身也有一塊新的業(yè)務(wù)在使用。 2018年5月19日,在上海舉行的第六屆中國PHP開發(fā)者大會(PHPCon)上,騰訊開源項目TARS首次全面發(fā)布PHP版本,閱文集團高級開發(fā)工程師梁晨對...
摘要:協(xié)程完全有用戶態(tài)程序控制,所以也被成為用戶態(tài)的線程。目前支持協(xié)程的語言有很多,例如等。協(xié)程之旅前篇結(jié)束,下一篇文章我們將深入分析原生協(xié)程部分的實現(xiàn)。 寫在最前 ??Swoole協(xié)程經(jīng)歷了幾個里程碑,我們需要在前進的道路上不斷總結(jié)與回顧自己的發(fā)展歷程,正所謂溫故而知新,本系列文章將分為協(xié)程之旅前、中、后三篇。 前篇主要介紹協(xié)程的概念和Swoole幾個版本協(xié)程實現(xiàn)的主要方案技術(shù); 中篇主...
閱讀 1368·2021-09-24 10:26
閱讀 3681·2021-09-06 15:02
閱讀 639·2019-08-30 14:18
閱讀 591·2019-08-30 12:44
閱讀 3130·2019-08-30 10:48
閱讀 1956·2019-08-29 13:09
閱讀 2010·2019-08-29 11:30
閱讀 2296·2019-08-26 13:36