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