摘要:協議在年誕生,年成為國際標準。手時不容易屏蔽,能通過各種代理服務器。沒有同源限制,客戶端可以與任意服務器通信。協議標識符是如果加密,則為,服務器網址就是。
WebSocket
WebSocket 協議在2008年誕生,2011年成為國際標準。所有瀏覽器都已經支持了。
它的最大特點就是,服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話,屬于服務器推送技術的一種。
為什么需要 WebSocket?需求是:用戶停留頁面 15 分鐘,且沒有任何操作,則彈出登陸窗口,讓用戶重新登陸。
一般這樣的需求實現多為長連接輪詢,會有瀏覽器的卡頓、服務端消耗及不容易維護等問題。
后來發現 websocket 這樣的通訊方式,主要有以下優點:
建立在 TCP 協議之上,服務器端的實現比較容易。
手時不容易屏蔽,能通過各種 HTTP 代理服務器。
數據格式比較輕量,性能開銷小,通信高效。
可以發送文本,也可以發送二進制數據。
沒有同源限制,客戶端可以與任意服務器通信。
協議標識符是ws(如果加密,則為wss),服務器網址就是 URL。
目標已經選定,那么如何實現呢?
PHP 已經有非常好用的異步網絡通信框架 swoole,節省了自己實現 websocket 服務的時間。我的使用的是 laravel 框架,最終選擇了 laravel-swoole 擴展。
安裝配置引入 laravel-swoole 擴展包 wiki 。啟用 websocket.enabled 及其他相應的配置,通過下面的命名可以非常方便的管理服務:
php artisan swoole:http {start|stop|restart|reload|infos}
修改配置文件中的默認 handler 配置為自定義的類:主要是為了自定義 websocket 的生命周期中的一些回調。
/* |-------------------------------------------------------------------------- | Websocket handler for onOpen and onClose callback | Replace this handler if you want to customize your websocket handler |-------------------------------------------------------------------------- */ "handler" => AppListenersSwooleWebsocketHandler::class, /* |-------------------------------------------------------------------------- | Default frame parser | Replace it if you want to customize your websocket payload |-------------------------------------------------------------------------- */ "parser" => SwooleTWHttpWebsocketSocketIOSocketIOParser::class,
當配置完成后,會在 routes 目錄中添加一個名為 websocket.php 的文件??梢苑浅7奖阆穸x laravel 路由一樣,定義各種事件。例如:
//Websocket::on("open", function ($websocket, Request $request) { // Log::info("websocket","open 111 +" . $websocket->getSender()); //}); // //Websocket::on("connect", function ($websocket, Request $request) { // Log::info("websocket","Connected ++ 222" . $websocket->getSender()); // // called while socket on connect. //}); // //Websocket::on("disconnect", function ($websocket) { // Log::info("websocket","Disconnected ++ 333" . $websocket->getSender()); // // called while socket on disconnect //}); // 在 UserController 中的 checkLogin 方法上會帶有$websocket, $data這兩個參數。 Websocket::on("loginCheck", "AppHttpControllersApiUserController@checkLogin"); Websocket::on("logout", "AppHttpControllersApiUserController@sendLogout");使用 控制器:
public function checkLogin($websocket, $data) { if (empty($data["holding"])) { $websocket->emit("message", ["code" => self::HTTP_UNPROCESSABLE_ENTITY, "message" => "參數錯誤"]); return false; } $flag = true; $step = 1; while ($flag) { $step++; if ( ! $this->validateLoginStatus($data["holding"])) { $websocket->emit("message", ["code" => self::HTTP_UNAUTHORIZED, "message" => "登陸超時"]); unset($step); $flag = false; }else { if($step === 1) { $websocket->emit("message", ["code" => self::HTTP_OK, "message" => "success"]); } } sleep(1); } }前端調用
這里一定要注意數據包的結構,之前就踩了比較多的坑,API docs 才找到正確的結構:
var websocket = new WebSocket("ws://127.0.0.1:1215"); websocket.onopen = function (evt) { console.log("已連接websocket服務器"); // 這里比較關鍵,通道建立后,可以進非常方便的進行輪詢 setInterval(function() { if (websocket.bufferedAmount == 0) var data = {"holding": "eyJLQNDqj0y473pCJ6zjMTUyOTk5NzU1MgnVMQ==$d84XkeMCv7umajhMRiU"}; websocket.send(encodeMessage("loginCheck", data)); }, 50); }; // 監聽消息體 websocket.onmessage = function (evt) { console.log(decodeMessage(evt.data)) }; // 監聽關閉消息 websocket.onclose = function (evt) { console.log("websocket close"); }; //監聽連接錯誤信息 websocket.onerror = function (evt) { console.log(evt); }; function decodeMessage(str) { return JSON.parse(str.substring(2))[1] || []; } function encodeMessage(event, data) { return JSON.stringify([ event, data ]) }Swoole擴展安裝
因為 swoole 的安裝依賴 php 的 sockets 模塊的開啟。
安裝 swoole
中間報錯,需要安裝以下依賴:
yum -y install gcc postgresql-devel gcc-c++
下載 swoole 擴展源碼,安裝 安裝步驟 進行安裝即可。
性能監控查看當前
$ netstat -n | awk "/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}" TIME_WAIT 814 CLOSE_WAIT 1 FIN_WAIT1 1 ESTABLISHED 634 SYN_RECV 2 LAST_ACK 1
常用的三個狀態是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。
刪除進程查看進程數
$ ps -eaf |grep "swoole" | grep -v "grep"| awk "{print $2}"|wc -l
批量刪除進程:
$ ps -eaf |grep "swoole" | grep -v "grep"| awk "{print $2}"|xargs kill -9
重啟服務。
參考文章阮一峰WebSocket教程
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106904.html
摘要:早期的輪詢是通過不斷自動刷新頁面而實現的。長輪詢的另一個問題是缺乏標準實現。服務器端接到這個請求后作出回應并不斷更新連接狀態以保證客戶端和服務器端的連接不過期。協議解析協議包含兩部分一部分是握手,一部分是數據傳輸。 Websocket是什么? Websocket是一個因為應用場景越來越復雜而提出的,針對瀏覽器和web服務器之間雙向持續通信而設計,而且優雅地兼容HTTP的協議(我猜想:同...
摘要:那么,是否就無法用來開發雙向通信的應用呢答案是否定的。內置通信支持,可以與程序基于進行雙向通信。通信協議于年被定為標準,并由補充規范。前言 眾所周知,PHP用于開發基于HTTP協議的網站應用非常便捷。而HTTP協議是一種單向的通信協議,只能接收客戶端的請求,然后響應請求,不能主動向客戶端推送信息。因此,一些實時性要求比較高的應用,如實時聊天、直播應用、在線網頁游戲等,就不適合采用HTTP協議...
摘要:那么,是否就無法用來開發雙向通信的應用呢答案是否定的。內置通信支持,可以與程序基于進行雙向通信。通信協議于年被定為標準,并由補充規范。前言 眾所周知,PHP用于開發基于HTTP協議的網站應用非常便捷。而HTTP協議是一種單向的通信協議,只能接收客戶端的請求,然后響應請求,不能主動向客戶端推送信息。因此,一些實時性要求比較高的應用,如實時聊天、直播應用、在線網頁游戲等,就不適合采用HTTP協議...
摘要:是一個請求對象,包含了客戶端發來的握手請求信息事件函數中可以調用向客戶端發送數據或者調用關閉連接事件回調是可選的當服務器收到來自客戶端的數據幀時會回調此函數。 前言:了解概念之后就應該練練手啦,不然就是巨嬰 有收獲的話請加顆小星星,沒有收獲的話可以 反對 沒有幫助 舉報三連 代碼倉庫 實戰swoole【聊天室】 在線體驗 準備工作 需要先看初識swoole【上】,了解基本的服務端...
摘要:進程可以使用函數向進程投遞新的任務。當前的進程在調用回調函數時會將進程狀態切換為忙碌,這時將不再接收新的,當函數返回時會將進程狀態切換為空閑然后繼續接收新的。當進程投遞的任務在中完成時,進程會通過方法將任務處理的結果發送給進程。 swoole——從入門到放棄(一) 一、swoole的源碼包安裝 下載swoole源碼:git clone https://gitee.com/swoole...
閱讀 2408·2021-11-23 09:51
閱讀 1219·2021-11-22 13:54
閱讀 3428·2021-09-24 10:31
閱讀 1095·2021-08-16 10:46
閱讀 3629·2019-08-30 15:54
閱讀 710·2019-08-30 15:54
閱讀 2892·2019-08-29 17:17
閱讀 3163·2019-08-29 15:08