摘要:項(xiàng)目中執(zhí)行以下命令即可三應(yīng)用在中結(jié)合消息隊(duì)列可參考使用隊(duì)列來(lái)完成消息推送。五配置如何創(chuàng)建一個(gè)服務(wù),使得客戶(hù)端可以用過(guò)協(xié)來(lái)連接通訊,比如在微信小程序中連接服務(wù)端。微信小程序要求連接時(shí)不帶端口號(hào),也就是端口只能是。
一、簡(jiǎn)述
GatewayWorker基于Workerman開(kāi)發(fā)的一個(gè)項(xiàng)目框架,用于快速開(kāi)發(fā)TCP長(zhǎng)連接應(yīng)用,例如app推送服務(wù)端、即時(shí)IM服務(wù)端、游戲服務(wù)端、物聯(lián)網(wǎng)、智能家居等等二、安裝GatewayWorker使用經(jīng)典的Gateway和Worker進(jìn)程模型。Gateway進(jìn)程負(fù)責(zé)維持客戶(hù)端連接,并轉(zhuǎn)發(fā)客戶(hù)端的數(shù)據(jù)給BusinessWorker進(jìn)程處理,BusinessWorker進(jìn)程負(fù)責(zé)處理實(shí)際的業(yè)務(wù)邏輯(默認(rèn)調(diào)用Events.php處理業(yè)務(wù)),并將結(jié)果推送給對(duì)應(yīng)的客戶(hù)端。Gateway服務(wù)和BusinessWorker服務(wù)可以分開(kāi)部署在不同的服務(wù)器上,實(shí)現(xiàn)分布式集群。
GatewayWorker提供非常方便的API,可以全局廣播數(shù)據(jù)、可以向某個(gè)群體廣播數(shù)據(jù)、也可以向某個(gè)特定客戶(hù)端推送數(shù)據(jù)。配合Workerman的定時(shí)器,也可以定時(shí)推送數(shù)據(jù)。
GatewayWorker 安裝在LInux服務(wù)器上:
下載地址:GatewayWorker
1、下載 demo
2、命令行運(yùn)行 unzip GatewayWorker.zip 解壓縮GatewayWorker.zip
3、命令行運(yùn)行 cd GatewayWorker 進(jìn)入GatewayWorker目錄
4、命令行運(yùn)行 php start.php start 啟動(dòng) GatewayWorker
5、新開(kāi)幾個(gè)命令行窗口運(yùn)行 telnet 127.0.0.1 8282,輸入任意字符即可聊天(非本機(jī)測(cè)試請(qǐng)將127.0.0.1替換成實(shí)際ip)。
注意:如果telnet超時(shí)請(qǐng)檢查服務(wù)器防火墻(iptables)
這里啟動(dòng)的是GatewayWorker的默認(rèn)端口,要是需要更改要改以下三個(gè)文件:
GatewayWorker/Applications/YourApp/start_register.php
// register 必須是text協(xié)議;這個(gè)端口要保持一致,根據(jù)項(xiàng)目自定義 $register = new Register("text://0.0.0.0:1238");
GatewayWorker/Applications/YourApp/start_businessworker.php
// bussinessWorker 進(jìn)程 $worker = new BusinessWorker(); // worker名稱(chēng),根據(jù)不同的項(xiàng)目自定義 $worker->name = "YourAppBusinessWorker"; // bussinessWorker進(jìn)程數(shù)量 $worker->count = 4; // 服務(wù)注冊(cè)地址; 注意這個(gè)端口要保持一致,不同的項(xiàng)目可以自定義 $worker->registerAddress = "127.0.0.1:1238";
GatewayWorker/Applications/YourApp/start_gateway.php
// gateway 進(jìn)程,這里使用Text協(xié)議,可以用telnet測(cè)試 $gateway = new Gateway("tcp://0.0.0.0:8282"); // gateway名稱(chēng),status方便查看 $gateway->name = "YourAppGateway"; // gateway進(jìn)程數(shù) $gateway->count = 4; // 本機(jī)ip,分布式部署時(shí)使用內(nèi)網(wǎng)ip $gateway->lanIp = "127.0.0.1"; // 內(nèi)部通訊起始端口,假如$gateway->count=4,起始端口為4000 // 則一般會(huì)使用4000 4001 4002 4003 4個(gè)端口作為內(nèi)部通訊端口 ,不同項(xiàng)目開(kāi)啟不同端口 $gateway->startPort = 2900; // 服務(wù)注冊(cè)地址;端口保持一致,項(xiàng)目自定義 $gateway->registerAddress = "127.0.0.1:1238"; // 服務(wù)端向客戶(hù)端發(fā)送心跳數(shù)據(jù)的時(shí)間間隔 單位:秒。如果設(shè)置為0代表不發(fā)送心跳檢測(cè) //$gateway->pingInterval = 10; //客戶(hù)端連續(xù)$pingNotResponseLimit次$pingInterval時(shí)間內(nèi)不回應(yīng)心跳則斷開(kāi)鏈接。 //如果設(shè)置為0代表客戶(hù)端不用發(fā)送回應(yīng)數(shù)據(jù),即通過(guò)TCP層面檢測(cè)連接的連通性(極端情況至少10分鐘才能檢測(cè)到) //$gateway->pingNotResponseLimit = 2; // 要發(fā)送的心跳請(qǐng)求數(shù)據(jù),心跳數(shù)據(jù)是任意的,只要客戶(hù)端能識(shí)別即可 //$gateway->pingData = "{"type":"ping"}";
注意:需要客戶(hù)端與服務(wù)端保持連接不被斷開(kāi),可以開(kāi)啟心跳檢查定時(shí)發(fā)送心跳數(shù)據(jù)。
服務(wù)管理
在GatewayWorker根目錄下有一個(gè)start.php文件:
php start.php start 啟動(dòng)服務(wù) (php start.php start -d 以daemon啟動(dòng)) php start.php stop 停止服務(wù) php start.php restart 重新啟動(dòng) (-d 以daemon啟動(dòng)) php start.php reload 平滑重啟 php start.php status 服務(wù)狀態(tài)
vagrant@homestead:~/code/GatewayWorker$ php start.php status Workerman[start.php] status ----------------------------------------------GLOBAL STATUS---------------------------------------------------- Workerman version:3.5.10 PHP version:7.2.3-1+ubuntu16.04.1+deb.sury.org+1 start time:2018-06-08 14:00:54 run 0 days 2 hours load average: 0, 0, 0 event-loop:WorkermanEventsSelect 3 workers 9 processes worker_name exit_status exit_count YourAppBusinessWorker 0 0 YourAppGateway 0 0 Register 0 0 ----------------------------------------------PROCESS STATUS--------------------------------------------------- pid memory listening worker_name connections send_fail timers total_request qps status 4693 2M none YourAppBusinessWorker 5 0 0 3 0 [idle] 4694 2M none YourAppBusinessWorker 5 0 0 3 0 [idle] 4695 2M none YourAppBusinessWorker 5 0 0 156 0 [idle] 4696 2M none YourAppBusinessWorker 5 0 0 3 0 [idle] 4697 2M tcp://0.0.0.0:8282 YourAppGateway 8 0 0 226 0 [idle] 4698 2M tcp://0.0.0.0:8282 YourAppGateway 8 0 0 226 0 [idle] 4699 2M tcp://0.0.0.0:8282 YourAppGateway 8 0 0 226 0 [idle] 4700 2M tcp://0.0.0.0:8282 YourAppGateway 8 0 0 378 0 [idle] 4701 2M text://0.0.0.0:1238 Register 8 0 0 51 0 [idle] ----------------------------------------------PROCESS STATUS--------------------------------------------------- Summary 18M - - 60 0 0 1272 0 [Summary]
注意:修改代碼要重啟服務(wù)。
GatewayClient安裝下項(xiàng)目中
原則:
現(xiàn)有mvc框架項(xiàng)目與GatewayWorker獨(dú)立部署互不干擾所有的業(yè)務(wù)邏輯都由網(wǎng)站頁(yè)面post/get到mvc框架中完成
GatewayWorker不接受客戶(hù)端發(fā)來(lái)的數(shù)據(jù),即GatewayWorker不處理任何業(yè)務(wù)邏輯,GatewayWorker僅僅當(dāng)做一個(gè)單向的推送通道
僅當(dāng)mvc框架需要向?yàn)g覽器主動(dòng)推送數(shù)據(jù)時(shí)才在mvc框架中調(diào)用Gateway的API(GatewayClient)完成推送
當(dāng)然,這只是官方推薦的結(jié)合方式,也不是絕對(duì)的。開(kāi)發(fā)者可以自由變化選擇結(jié)合方式以適應(yīng)自己的業(yè)務(wù)需求。 當(dāng)然也可以采用客戶(hù)端與GatewayWorker直接雙向通訊的方式完成業(yè)務(wù)通訊。更多參考官方手冊(cè)。
下載地址:GatewayClient。項(xiàng)目中執(zhí)行以下命令即可:
composer require workerman/gatewayclient三、應(yīng)用
在laravel中結(jié)合redis 消息隊(duì)列(可參考laravel/lumen 使用 redis隊(duì)列)來(lái)完成消息推送。
在controller中使用dispatch觸發(fā)隊(duì)列
dispatch(new YourJob($data));
在Jobs中示例:
id = $id; } public function handle() { //業(yè)務(wù)邏輯 Gateway::sendToAll(json_encode(["id" => xxx, "name" => xxx])); } }
每次改動(dòng)代碼重啟隊(duì)列。supervisorctl reload四、調(diào)試
服務(wù)器端打開(kāi)Telnet,不可執(zhí)行Telnet命令需要安裝。
如:
vagrant@homestead:~/code/GatewayWorker$ telnet 127.0.0.1 8282 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is "^]". Hello 7f0000010b5600000001 7f0000010b5600000001 login hello 7f0000010b5600000001 said hello {"id":"35","name":"xxx"}
正常情況,會(huì)輸出你想發(fā)送的消息。
Escape character is "^]".是 Ctrl + ] 調(diào)出Telnet,輸入quit可以退出。
Workerman如何創(chuàng)建一個(gè)wss服務(wù),使得客戶(hù)端可以用過(guò)wss協(xié)來(lái)連接通訊,比如在微信小程序中連接服務(wù)端。
wss協(xié)議實(shí)際是websocket+SSL,就是在websocket協(xié)議上加入SSL層,類(lèi)似https(http+SSL)。 所以只需要在websocket協(xié)議的基礎(chǔ)上開(kāi)啟SSL即可支持wss協(xié)議。
配置方式一:直接用Workerman開(kāi)啟SSL:
準(zhǔn)備工作:
1、Workerman版本不小于3.3.7
2、PHP安裝了openssl擴(kuò)展
3、已經(jīng)申請(qǐng)了證書(shū)(pem/crt文件及key文件)放在磁盤(pán)任意目錄
start_gateway.php中設(shè)置以下代碼
array( // 請(qǐng)使用絕對(duì)路徑 "local_cert" => "磁盤(pán)路徑/server.pem", // 也可以是crt文件 "local_pk" => "磁盤(pán)路徑/server.key", "verify_peer" => false, // "allow_self_signed" => true, //如果是自簽名證書(shū)需要開(kāi)啟此選項(xiàng) ) ); // 這里設(shè)置的是websocket協(xié)議(端口任意,但是需要保證沒(méi)被其它程序占用) $worker = new Worker("websocket://0.0.0.0:443", $context); $worker->name = xxx //配置名稱(chēng)便于監(jiān)控 // 設(shè)置transport開(kāi)啟ssl,websocket+ssl即wss $worker->transport = "ssl"; $worker->onMessage = function($con, $msg) { $con->send("ok"); }; Worker::runAll();
通過(guò)以上的代碼,Workerman就監(jiān)聽(tīng)了wss協(xié)議,客戶(hù)端就可以通過(guò)wss協(xié)議來(lái)連接workerman實(shí)現(xiàn)安全即時(shí)通訊了。
測(cè)試
打開(kāi)chrome瀏覽器,按F12打開(kāi)調(diào)試控制臺(tái),在Console一欄輸入(或者把下面代碼放入到html頁(yè)面用js運(yùn)行)
// 證書(shū)是會(huì)檢查域名的,請(qǐng)使用域名連接
ws = new WebSocket("wss://域名"); ws.onopen = function() { alert("連接成功"); ws.send("tom"); alert("給服務(wù)端發(fā)送一個(gè)字符串:tom"); }; ws.onmessage = function(e) { alert("收到服務(wù)端的消息:" + e.data); };
注意:1、如果無(wú)法啟動(dòng),則一般是443端口被占用,請(qǐng)改成其它端口,注意改成其它端口后客戶(hù)端連接時(shí)需要帶上端口號(hào),客戶(hù)端連接時(shí)地址類(lèi)似wss://domain.com:xxx ,xxx為端口號(hào)。如果必須使用443端口請(qǐng)使用方法二代理的方式實(shí)現(xiàn)wss。
2、wss端口只能通過(guò)wss協(xié)議訪(fǎng)問(wèn),ws無(wú)法訪(fǎng)問(wèn)wss端口。
3、證書(shū)一般是與域名綁定的,所以測(cè)試的時(shí)候客戶(hù)端請(qǐng)使用域名連接,不要使用ip去連。
4、如果出現(xiàn)無(wú)法訪(fǎng)問(wèn)的情況,請(qǐng)檢查服務(wù)器防火墻。
5、此方法要求PHP版本>=5.6,因?yàn)槲⑿判〕绦蛞?b>tls1.2,而PHP5.6以下版本不支持tls1.2。
6、微信小程序要求連接wss時(shí)不帶端口號(hào),也就是wss端口只能是443。但是443端口一般被nginx/apache占用,此時(shí)可以考慮方法二。
配置方式二:利用nginx/apache代理wss
利用nginx/apache作為wss代理轉(zhuǎn)發(fā)給workerman(注意此方法workerman部分千萬(wàn)不要設(shè)置ssl,否則將無(wú)法連接)。
通訊原理及流程是:1、客戶(hù)端發(fā)起wss連接連到nginx/apache
2、nginx/apache將wss協(xié)議的數(shù)據(jù)轉(zhuǎn)換成ws協(xié)議數(shù)據(jù)并轉(zhuǎn)發(fā)到Workerman的websocket協(xié)議端口
3、Workerman收到數(shù)據(jù)后做業(yè)務(wù)邏輯處理
4、Workerman給客戶(hù)端發(fā)送消息時(shí),則是相反的過(guò)程,數(shù)據(jù)經(jīng)過(guò)nginx/apache轉(zhuǎn)換成wss協(xié)議然后發(fā)給客戶(hù)端
nginx配置參考
前提條件及準(zhǔn)備工作:1、假設(shè)Workerman監(jiān)聽(tīng)的是8282端口(websocket協(xié)議,不要用tcp)
2、已經(jīng)申請(qǐng)了證書(shū)(pem/crt文件及key文件)放在了/etc/nginx/conf.d/ssl下
3、打算利用nginx開(kāi)啟443端口對(duì)外提供wss代理服務(wù)(端口可以根據(jù)需要修改)
4、nginx一般作為網(wǎng)站服務(wù)器運(yùn)行著其它服務(wù),為了不影響原來(lái)的站點(diǎn)使用,這里使用地址 域名/wss 作為wss的代理入口。也就是客戶(hù)端連接地址為 wss://域名/wss
nginx配置類(lèi)似如下:
server { listen 443; ssl on; ssl_certificate /etc/ssl/server.pem; ssl_certificate_key /etc/ssl/server.key; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; ssl_protocols SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; location /wss { proxy_pass http://127.0.0.1:8282; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; } # location / {} 站點(diǎn)的其它配置... }
測(cè)試
// 證書(shū)是會(huì)檢查域名的,請(qǐng)使用域名連接
ws = new WebSocket("wss://域名/wss"); ws.onopen = function() { alert("連接成功"); ws.send("tom"); alert("給服務(wù)端發(fā)送一個(gè)字符串:tom"); }; ws.onmessage = function(e) { alert("收到服務(wù)端的消息:" + e.data); };
另外為了方便測(cè)試,大家也可以使用在線(xiàn)測(cè)試工具,如 websocket在線(xiàn)測(cè)試
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28783.html
摘要:客戶(hù)端源碼服務(wù)端源碼實(shí)現(xiàn)實(shí)時(shí)聊天功能它是什么基于的有前端有后端的支持分布式部署的網(wǎng)頁(yè)版實(shí)時(shí)聊天。個(gè)人認(rèn)為就是為的后端而生的,簡(jiǎn)直是無(wú)縫結(jié)合起來(lái)。個(gè)人只在當(dāng)中使用把和串連起來(lái),解決了沒(méi)有后端的尷尬境地。 LayIM客戶(hù)端源碼 LayIM服務(wù)端源碼 Laravel+Layim+GatewayWorker實(shí)現(xiàn)實(shí)時(shí)聊天功能 它是什么? 基于wbsocket的有前端有后端的支持分布式部署的網(wǎng)頁(yè)版...
摘要:即時(shí)通訊中,最重要的是響應(yīng)速度,我們需要展示消息列表那么這時(shí)會(huì)有未讀消息,未讀數(shù)量,最后一條消息內(nèi)容,時(shí)間等等。目前設(shè)計(jì)是單表單庫(kù)。這里只是對(duì)即時(shí)通訊設(shè)計(jì)上做了一些簡(jiǎn)要的闡述,如有疑問(wèn)和建議,請(qǐng)?jiān)谠u(píng)論區(qū)回復(fù)。 詳解即時(shí)通訊設(shè)計(jì)實(shí)現(xiàn)(PHP+GatewayWorker+Redis) 需要實(shí)現(xiàn)的功能 一對(duì)一聊天(私聊) 一對(duì)多聊天(群聊) 類(lèi)似QQ,微信等聊天列表 實(shí)時(shí)消息 顯示 工具...
摘要:即時(shí)通訊中,最重要的是響應(yīng)速度,我們需要展示消息列表那么這時(shí)會(huì)有未讀消息,未讀數(shù)量,最后一條消息內(nèi)容,時(shí)間等等。目前設(shè)計(jì)是單表單庫(kù)。這里只是對(duì)即時(shí)通訊設(shè)計(jì)上做了一些簡(jiǎn)要的闡述,如有疑問(wèn)和建議,請(qǐng)?jiān)谠u(píng)論區(qū)回復(fù)。 詳解即時(shí)通訊設(shè)計(jì)實(shí)現(xiàn)(PHP+GatewayWorker+Redis) 需要實(shí)現(xiàn)的功能 一對(duì)一聊天(私聊) 一對(duì)多聊天(群聊) 類(lèi)似QQ,微信等聊天列表 實(shí)時(shí)消息 顯示 工具...
閱讀 3258·2021-10-21 17:50
閱讀 3264·2021-10-08 10:05
閱讀 3400·2021-09-22 15:04
閱讀 589·2019-08-30 14:00
閱讀 1951·2019-08-29 17:01
閱讀 1517·2019-08-29 15:16
閱讀 3227·2019-08-26 13:25
閱讀 860·2019-08-26 11:44