本篇內(nèi)容介紹了“PHP+Socket中IO多路復(fù)用及實(shí)現(xiàn)web服務(wù)器的方法是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)公司是一家專(zhuān)注于網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站與策劃設(shè)計(jì),韓城網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:韓城等地區(qū)。韓城做網(wǎng)站價(jià)格咨詢(xún):18982081108
多路復(fù)用
前文 通過(guò)原生 socket 實(shí)現(xiàn)了簡(jiǎn)單的服務(wù)端與客戶(hù)端通信,但當(dāng)有多個(gè)客戶(hù)端連接時(shí),服務(wù)端僅能處理第一個(gè)客戶(hù)端的請(qǐng)求,而無(wú)法對(duì)后續(xù)客戶(hù)端服務(wù)
產(chǎn)生這種情況的原因是因?yàn)镮O模型是阻塞的,同一時(shí)刻只能由一個(gè)客戶(hù)端進(jìn)行訪(fǎng)問(wèn),解決此問(wèn)題主要有兩種解決方案:
多進(jìn)程,即在服務(wù)端啟動(dòng)多個(gè)進(jìn)程監(jiān)聽(tīng)
IO多路復(fù)用機(jī)制,簡(jiǎn)單來(lái)說(shuō)實(shí)現(xiàn)了 N 個(gè)客戶(hù)端使用一根網(wǎng)線(xiàn)同時(shí)訪(fǎng)問(wèn)
同時(shí)多路復(fù)用又分為兩個(gè)不同的模型,即 select
與 epoll
,常見(jiàn)的軟件中,Apache
使用了 select
模型,nginx
則使用 epoll
模型。在 php 中內(nèi)置了 select
模型,對(duì)應(yīng)的函數(shù)為 socket_select
,多路復(fù)用是實(shí)現(xiàn) http 服務(wù)器的基礎(chǔ)
在前文中我們介紹了 php 原生 socket 內(nèi)置了 socket_select
函數(shù)實(shí)現(xiàn)了 select
模型,其語(yǔ)法如下:
socket_select(
array &$read,
array &$write,
array &$except,
int $seconds [,
int $microseconds = 0]): int|false
read
服務(wù)端監(jiān)聽(tīng)的套接字資源,當(dāng)他有變化(即收到新的消息或有客戶(hù)端連接、斷開(kāi))時(shí),socket_select
函數(shù)才會(huì)返回(否則繼續(xù)阻塞),同時(shí)修改該變量為當(dāng)前發(fā)生事件(收到消息或有客戶(hù)端連接、斷開(kāi))的套接字資源列表,并繼續(xù)向下執(zhí)行。
write
監(jiān)聽(tīng)是否有客戶(hù)端寫(xiě)數(shù)據(jù),傳入 null
則代表不關(guān)心是否有寫(xiě)變化
except
套接字內(nèi)要排除的元素,傳入 null
是 「監(jiān)聽(tīng)」 全部
seconds
秒和微秒一起構(gòu)成超時(shí)參數(shù)。如果傳入 null
則會(huì)阻塞,為 0 非阻塞,如果是 >0 則為最大阻塞時(shí)間
microseconds
我們?cè)?上篇文章 簡(jiǎn)單實(shí)現(xiàn)了 socket 服務(wù)端監(jiān)聽(tīng)與客戶(hù)端的連接,接下來(lái)我們?cè)诜?wù)端監(jiān)聽(tīng)代碼的基礎(chǔ)上通過(guò)多路復(fù)用優(yōu)化代碼:
在本示例中 socket_select
函數(shù)會(huì)阻塞當(dāng)前進(jìn)程,當(dāng) $tmp_sockets
數(shù)組內(nèi)的 socket 資源有新的客戶(hù)端連接或斷開(kāi)或收到新消息時(shí),會(huì)將 $tmp_sockets
數(shù)組修改為當(dāng)前活躍的 socket 資源,隨后通過(guò)遍歷該數(shù)組處理業(yè)務(wù)邏輯。
使用socket實(shí)現(xiàn)簡(jiǎn)易http服務(wù)器
http 協(xié)議是在 socket 的基礎(chǔ)上規(guī)定了指定的數(shù)據(jù)格式,所以我們只需在 socket_write
時(shí)按照格式發(fā)送數(shù)據(jù),瀏覽器就可正常響應(yīng)請(qǐng)求
this is php worker';
$len = strlen($output);
$response = "HTTP/1.1 200 OK\r\n";
$response .= "content-type: text/html\r\n";
$response .= "server: php socket\r\n";
$response .= "Content-Length: {$len}\r\n\r\n";
$response .= $output;
socket_write($sock, $response);
}
}
}
在服務(wù)端運(yùn)行此示例,隨后在瀏覽器訪(fǎng)問(wèn) ip:8888
,可以看到如下:
同時(shí)服務(wù)端會(huì)輸出如下內(nèi)容:
GET / HTTP/1.1
Host: 124.222.**.**:8888
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: jenkins-timestamper-offset=-28800000; _ga=GA1.1.1403944751.1652010033; _ga_2GM6102E19=GS1.1.1652802985.7.1.1652803014.0
該內(nèi)容即為用戶(hù)端請(qǐng)求原始數(shù)據(jù),可解析此數(shù)據(jù)并根據(jù)請(qǐng)求做出響應(yīng),比如使用 file_get_content
讀取指定文件內(nèi)容返回給瀏覽器。
“PHP+Socket中IO多路復(fù)用及實(shí)現(xiàn)web服務(wù)器的方法是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!