php-fpm應(yīng)用與php-swoole應(yīng)用進(jìn)行通信
2020-04-26
基礎(chǔ)要求
linux萬(wàn)物皆文件
socket通信
基礎(chǔ)進(jìn)制轉(zhuǎn)換
寫在前面
這篇文章是自己練習(xí)的內(nèi)容,主要想實(shí)現(xiàn)應(yīng)用間的通信機(jī)制。
Workerman中提供的建議方案
與其它mvc框架結(jié)合建議以上圖的方式(ThinkPHP為例):
1、ThinkPHP與Workerman是兩個(gè)獨(dú)立的系統(tǒng),獨(dú)立部署(可部署在不同服務(wù)器),互不干擾。
2、ThinkPHP以HTTP協(xié)議提供網(wǎng)頁(yè)頁(yè)面在瀏覽器渲染展示。
3、ThinkPHP提供的頁(yè)面的js發(fā)起websocket連接,連接workerman
4、連接后給Workerman發(fā)送一個(gè)數(shù)據(jù)包(包含用戶名密碼或者某種token串)用于驗(yàn)證websocket連接屬于哪個(gè)用戶。
5、僅在ThinkPHP需要向?yàn)g覽器推送數(shù)據(jù)時(shí),才調(diào)用workerman的socket接口推送數(shù)據(jù)。
6、其余請(qǐng)求還是按照原本ThinkPHP的HTTP方式調(diào)用處理。
總結(jié):
把Workerman作為一個(gè)可以向?yàn)g覽器推送的通道,僅僅在需要向?yàn)g覽器推送數(shù)據(jù)時(shí)才調(diào)用Workerman接口完成推送。業(yè)務(wù)邏輯全部在ThinkPHP中完成。
我們使用swoole環(huán)境的常駐內(nèi)存、協(xié)程特性來(lái)做一些其他事務(wù),如:任務(wù)隊(duì)列及其消費(fèi)、緩存、異步執(zhí)行等情況時(shí)
可以如建議中第5步所說(shuō),F(xiàn)PM環(huán)境調(diào)用Swoole環(huán)境提供的接口(可以用TCP/HTTP等方式)來(lái)開始一個(gè)任務(wù)
進(jìn)程通信
上面的方案可以用在單機(jī)中,也可以用在集群部署中。
進(jìn)程通信一般僅限于單機(jī)中使用
進(jìn)程通信的方式有好幾種,這里主要寫明我測(cè)試的一種。
unix socket 文件
在linux環(huán)境中,萬(wàn)物皆為文件,套接字也可以用文件來(lái)表示,然后一個(gè)進(jìn)程(一般是swoole環(huán)境)監(jiān)聽它,其他進(jìn)程(FPM環(huán)境)連接它,并且發(fā)送數(shù)據(jù)
這里使用的是Easyswoole框架提供的一個(gè)基類,如果是純Swoole環(huán)境可以下載框架源碼并查看原理
EasySwoole部分
繼承了 AbstractUnixProcess
,封裝好了很多內(nèi)容,直接寫明onAccept 接受數(shù)據(jù)做處理即可
\; \\\\; \\; { (Socket $socket) { $header = $socket->recvAll(, ); (strlen($header) != ) { $socket->sendAll(::pack(json_encode([ => , => , ], ))); $socket->close(); ; } $allLength = ::packDataLength($header); $data = $socket->recvAll($allLength, ); (strlen($data) == $allLength) { $data; $socket->sendAll(::pack(json_encode([ => , => , ], ))); $socket->close(); }{ $socket->sendAll(::pack(json_encode([ => , => , ], ))); $socket->close(); } } ($string) { pack(, strlen($string)) . $string; } ($head) { unpack(, $head)[]; } }
寫好了任務(wù)邏輯,還需要加入啟動(dòng)該進(jìn)程
EasySwooleEvent.php文件 (EventRegister $register) { $config = UnixProcessConfig(); $config->setSocketFile(EASYSWOOLE_ROOT.); $config->setProcessName(); $siam = Siam($config); ServerManager::getInstance()->getSwooleServer()->addProcess($siam->getProcess()); }
普通環(huán)境發(fā)送數(shù)據(jù)
$sock = dirname().; $unixSock = stream_socket_client(.$sock); fwrite($unixSock, siam_pack()); fclose($unixSock); ($string) { pack(, strlen($string)) . $string; } ($head) { unpack(, $head)[]; }