摘要:背景最近在一些項(xiàng)目需要用到實(shí)時(shí)推送給分組的用戶,前端需要傳輸給后端的信息比較少,通過多方考慮選擇了通過框架基于搭建微服務(wù)。擁有定時(shí)器異步客戶端異步異步異步異步消息隊(duì)列等眾多高性能組件。配合的定時(shí)器,也可以定時(shí)推送數(shù)據(jù)。
背景
最近在一些項(xiàng)目需要用到Websocket實(shí)時(shí)推送給分組的用戶,前端需要傳輸給后端的信息比較少,通過多方考慮選擇了通過GatewayWorker框架(基于Workerman)搭建微服務(wù)。
介紹 WorkermanWorkerman是一款純PHP開發(fā)的開源高性能的PHP socket 服務(wù)框架。
Workerman不是重復(fù)造輪子,它不是一個(gè)MVC框架,而是一個(gè)更底層更通用的socket服務(wù)框架,你可以用它開發(fā)tcp代理、梯子代理、做游戲服務(wù)器、郵件服務(wù)器、ftp服務(wù)器、甚至開發(fā)一個(gè)php版本的redis、php版本的數(shù)據(jù)庫、php版本的nginx、php版本的php-fpm等等。Workerman可以說是PHP領(lǐng)域的一次創(chuàng)新,讓開發(fā)者徹底擺脫了PHP只能做WEB的束縛。
實(shí)際上Workerman類似一個(gè)PHP版本的nginx,核心也是多進(jìn)程+Epoll+非阻塞IO。Workerman每個(gè)進(jìn)程能維持上萬并發(fā)連接。由于本身常住內(nèi)存,不依賴Apache、nginx、php-fpm這些容器,擁有超高的性能。同時(shí)支持TCP、UDP、UNIXSOCKET,支持長連接,支持Websocket、HTTP、WSS、HTTPS等通訊協(xié)以及各種自定義協(xié)議。擁有定時(shí)器、異步socket客戶端、異步Mysql、異步Redis、異步Http、異步消息隊(duì)列等眾多高性能組件。
github地址:https://github.com/walkor/Workerman
文檔:http://doc.workerman.net/315110
GatewayWorkerGatewayWorker基于Workerman開發(fā)的一個(gè)項(xiàng)目框架,用于快速開發(fā)TCP長連接應(yīng)用,例如app推送服務(wù)端、即時(shí)IM服務(wù)端、游戲服務(wù)端、物聯(lián)網(wǎng)、智能家居等等
GatewayWorker使用經(jīng)典的Gateway和Worker進(jìn)程模型。Gateway進(jìn)程負(fù)責(zé)維持客戶端連接,并轉(zhuǎn)發(fā)客戶端的數(shù)據(jù)給BusinessWorker進(jìn)程處理,BusinessWorker進(jìn)程負(fù)責(zé)處理實(shí)際的業(yè)務(wù)邏輯(默認(rèn)調(diào)用Events.php處理業(yè)務(wù)),并將結(jié)果推送給對應(yīng)的客戶端。Gateway服務(wù)和BusinessWorker服務(wù)可以分開部署在不同的服務(wù)器上,實(shí)現(xiàn)分布式集群。
GatewayWorker提供非常方便的API,可以全局廣播數(shù)據(jù)、可以向某個(gè)群體廣播數(shù)據(jù)、也可以向某個(gè)特定客戶端推送數(shù)據(jù)。配合Workerman的定時(shí)器,也可以定時(shí)推送數(shù)據(jù)。
github地址:https://github.com/walkor/GatewayWorker
文檔:http://doc2.workerman.net/326102
Workerman與GatewayWorker的關(guān)系Workerman可以看做是一個(gè)純粹的socket類庫,可以開發(fā)幾乎所有的網(wǎng)絡(luò)應(yīng)用,不管是TCP的還是UDP的,長連接的還是短連接的。Workerman代碼精簡,功能強(qiáng)大,使用靈活,能夠快速開發(fā)出各種網(wǎng)絡(luò)應(yīng)用。同時(shí)Workerman相比GatewayWorker也更底層,需要開發(fā)者有一定的多進(jìn)程編程經(jīng)驗(yàn)。
因?yàn)榻^大多數(shù)開發(fā)者的目標(biāo)是基于Workerman開發(fā)TCP長連接應(yīng)用,而長連接應(yīng)用服務(wù)端有很多共同之處,例如它們有相同的進(jìn)程模型以及單發(fā)、群發(fā)、廣播等接口需求。所以才有了GatewayWorker框架,GatewayWorker是基于Workerman開發(fā)的一個(gè)TCP長連接框架,實(shí)現(xiàn)了單發(fā)、群送、廣播等長連接必用的接口。GatewayWorker框架實(shí)現(xiàn)了Gateway Worker進(jìn)程模型,天然支持分布式多服務(wù)器部署,擴(kuò)容縮容非常方便,能夠應(yīng)對海量并發(fā)連接??梢哉fGatewayWorker是基于Workerman實(shí)現(xiàn)的一個(gè)更完善的專門用于實(shí)現(xiàn)TCP長連接的項(xiàng)目框架。
GatewayClientGatewayClient是GatewayWorker的客戶端程序,可以進(jìn)行推送、分組、統(tǒng)計(jì)等操作。
websocket微服務(wù)介紹總體原則,websocket微服務(wù)不處理業(yè)務(wù)邏輯,僅僅是一個(gè)單向連接,只負(fù)責(zé)推送信息。但客戶端連接websocket微服務(wù)時(shí),websocket微服務(wù)返回給客戶端clientId,客戶端調(diào)用接口把clientId傳給后端,此時(shí)后端就可以通過GatewayClient綁定用戶到具體分組。但需要推送時(shí),通過text協(xié)議與GatewayWorker通信,把要推送的clientId或者分組傳給GatewayWorker,GatewayWorker再推送給客戶端。圖示如下:
具體實(shí)現(xiàn) 安裝GatewayWorker內(nèi)核新建一個(gè)空白項(xiàng)目(不在Laravel/Lumen/ThinkPHP 等PHP框架里),執(zhí)行
composer require workerman/gateway-worker啟動文件
在根目錄新建start.php作為啟動文件,代碼:
注冊Register類Register類負(fù)責(zé)注冊內(nèi)部通訊地址。Gateway進(jìn)程和BusinessWorker進(jìn)程啟動后分別向Register進(jìn)程注冊自己的通訊地址,Gateway進(jìn)程和BusinessWorker通過Register進(jìn)程得到通訊地址后,就可以建立起連接并通訊了。
GatewayWorker工作原理
src/start_register.php (目錄名可以自己定義) 代碼:
注冊Gateway類Gateway類用于初始化Gateway進(jìn)程。Gateway進(jìn)程是暴露給客戶端的讓其連接的進(jìn)程。所有客戶端的請求都是由Gateway接收然后分發(fā)給BusinessWorker處理,同樣BusinessWorker也會將要發(fā)給客戶端的響應(yīng)通過Gateway轉(zhuǎn)發(fā)出去。
src/start_gateway.php 代碼:
name = "business-gateway"; // gateway進(jìn)程數(shù) $gateway->count = 2; // 本機(jī)ip,分布式部署時(shí)使用內(nèi)網(wǎng)ip $gateway->lanIp = "127.0.0.1"; // 內(nèi)部通訊起始端口,假如$gateway->count=4,起始端口為4000 // 則一般會使用4000 4001 4002 4003 4個(gè)端口作為內(nèi)部通訊端口 $gateway->startPort = 2900; // 服務(wù)注冊地址(register類地址) $gateway->registerAddress = "127.0.0.1:1238";注冊BusinessWorker類BusinessWorker是運(yùn)行業(yè)務(wù)邏輯的進(jìn)程,BusinessWorker收到Gateway轉(zhuǎn)發(fā)來的事件及請求時(shí)會默認(rèn)調(diào)用Events.php中的onConnect onMessage onClose方法處理事件及數(shù)據(jù),開發(fā)者正是通過實(shí)現(xiàn)這些回調(diào)控制業(yè)務(wù)及流程。
src/start_businessworker.php 代碼:
name = "Steam-BusinessWorker"; // bussinessWorker進(jìn)程數(shù)量 $worker->count = 1; // 服務(wù)注冊地址 $worker->registerAddress = "127.0.0.1:1238";Events類Events類用于捕獲GatewayWorker事件,在這里可以寫一些回調(diào)信息。
src/Events.php 代碼:
$client_id, ])); } /** * 當(dāng)客戶端發(fā)來消息時(shí)觸發(fā) * @param int $client_id 連接id * @param mixed $message 具體消息 */ public static function onMessage($client_id, $message) { } /** * 當(dāng)用戶斷開連接時(shí)觸發(fā) * @param int $client_id 連接id */ public static function onClose($client_id) { } }在PHP項(xiàng)目分組或推送給客戶端這是在你自己的項(xiàng)目寫的代碼,過程:前端調(diào)用接口傳來clientId,后端綁定到分組,再推送信息給分組或者指定的clientId客戶端。
需要在項(xiàng)目中引用GatewayClient包
composer require workerman/gatewayclient代碼:
// GatewayClient 3.0.0版本以后加了命名空間 use GatewayClientGateway; /** * === 指定registerAddress表明與哪個(gè)GatewayWorker(集群)通訊。=== * GatewayWorker里用Register服務(wù)來區(qū)分集群,即一個(gè)GatewayWorker(集群)只有一個(gè)Register服務(wù), * GatewayClient要與之通訊必須知道這個(gè)Register服務(wù)地址才能通訊,這個(gè)地址格式為 ip:端口 , * 其中ip為Register服務(wù)運(yùn)行的ip(如果GatewayWorker是單機(jī)部署則ip就是運(yùn)行GatewayWorker的服務(wù)器ip), * 端口是對應(yīng)ip的服務(wù)器上start_register.php文件中監(jiān)聽的端口,也就是GatewayWorker啟動時(shí)看到的Register的端口。 * GatewayClient要想推送數(shù)據(jù)給客戶端,必須知道客戶端位于哪個(gè)GatewayWorker(集群), * 然后去連這個(gè)GatewayWorker(集群)Register服務(wù)的 ip:端口,才能與對應(yīng)GatewayWorker(集群)通訊。 * 這個(gè) ip:端口 在GatewayClient一側(cè)使用 Gateway::$registerAddress 來指定。 * * === 如果GatewayClient和GatewayWorker不在同一臺服務(wù)器需要以下步驟 === * 1、需要設(shè)置start_gateway.php中的lanIp為實(shí)際的本機(jī)內(nèi)網(wǎng)ip(如不在一個(gè)局域網(wǎng)也可以設(shè)置成外網(wǎng)ip),設(shè)置完后要重啟GatewayWorker * 2、GatewayClient這里的Gateway::$registerAddress的ip填寫填寫上面步驟1lanIp所指定的ip,端口 * 3、需要開啟GatewayWorker所在服務(wù)器的防火墻,讓以下端口可以被GatewayClient所在服務(wù)器訪問, * 端口包括Rgister服務(wù)的端口以及start_gateway.php中l(wèi)anIp與startPort指定的幾個(gè)端口 * * === 如果GatewayClient和GatewayWorker在同一臺服務(wù)器 === * GatewayClient和Register服務(wù)都在一臺服務(wù)器上,ip填寫127.0.0.1及即可,無需其它設(shè)置。 **/ Gateway::$registerAddress = "127.0.0.1:1236"; // GatewayClient支持GatewayWorker中的所有接口(Gateway::closeCurrentClient Gateway::sendToCurrentClient除外) Gateway::sendToAll($data); Gateway::sendToClient($client_id, $data); Gateway::closeClient($client_id); Gateway::isOnline($client_id); Gateway::bindUid($client_id, $uid); Gateway::isUidOnline($uid); Gateway::getClientIdByUid($client_id); Gateway::unbindUid($client_id, $uid); Gateway::sendToUid($uid, $dat); Gateway::joinGroup($client_id, $group); Gateway::sendToGroup($group, $data); Gateway::leaveGroup($client_id, $group); Gateway::getClientCountByGroup($group); Gateway::getClientSessionsByGroup($group); Gateway::getAllClientCount(); Gateway::getAllClientSessions(); Gateway::setSession($client_id, $session); Gateway::updateSession($client_id, $session); Gateway::getSession($client_id);原文:https://www.wugenglong.com/We...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/28965.html
摘要:作為微服務(wù)的基礎(chǔ)設(shè)施之一,背靠強(qiáng)大的生態(tài)社區(qū),支撐技術(shù)體系。微服務(wù)實(shí)踐為系列講座,專題直播節(jié),時(shí)長高達(dá)小時(shí),包括目前最流行技術(shù),深入源碼分析,授人以漁的方式,幫助初學(xué)者深入淺出地掌握,為高階從業(yè)人員拋磚引玉。 簡介 目前業(yè)界最流行的微服務(wù)架構(gòu)正在或者已被各種規(guī)模的互聯(lián)網(wǎng)公司廣泛接受和認(rèn)可,業(yè)已成為互聯(lián)網(wǎng)開發(fā)人員必備技術(shù)。無論是互聯(lián)網(wǎng)、云計(jì)算還是大數(shù)據(jù),Java平臺已成為全棧的生態(tài)體系,...
摘要:開公眾號差不多兩年了,有不少原創(chuàng)教程,當(dāng)原創(chuàng)越來越多時(shí),大家搜索起來就很不方便,因此做了一個(gè)索引幫助大家快速找到需要的文章系列處理登錄請求前后端分離一使用完美處理權(quán)限問題前后端分離二使用完美處理權(quán)限問題前后端分離三中密碼加鹽與中異常統(tǒng)一處理 開公眾號差不多兩年了,有不少原創(chuàng)教程,當(dāng)原創(chuàng)越來越多時(shí),大家搜索起來就很不方便,因此做了一個(gè)索引幫助大家快速找到需要的文章! Spring Boo...
閱讀 1090·2021-11-24 09:39
閱讀 1321·2021-11-18 13:18
閱讀 2472·2021-11-15 11:38
閱讀 1841·2021-09-26 09:47
閱讀 1643·2021-09-22 15:09
閱讀 1637·2021-09-03 10:29
閱讀 1524·2019-08-29 17:28
閱讀 2963·2019-08-29 16:30