WebSocket服務(wù)對于 Web 應(yīng)用來說,最主流的當(dāng)然就是我們之前學(xué)習(xí)過的 Http、TCP、UDP 這一類的應(yīng)用。但是,最近這些年,特別是 HTML5 成為主流之后,WebSocket 應(yīng)用日益豐富起來。要知道,之前我們在做后臺時,如果要做消息通知之類的應(yīng)用,全都是使用 JQuery 來進(jìn)行 Ajax 輪詢的。對于后臺來說,這么做問題不大,但是如果你是要在前端頁面做類似的功能,特別是一些客服功能的話,那可就費勁了。 關(guān)于 WebSocket 的好處我也不多說了,大家可以自己去查閱一下相關(guān)的資料。最主要的是,它建立起來的是一個持久的長鏈接,不需要像輪詢一樣不停地發(fā)送 Http 請求,能夠非常有效地節(jié)省服務(wù)器資源。 之前我們在 Laravel 系列課程中就學(xué)習(xí)過它的 廣播系統(tǒng) ,這個 廣播系統(tǒng) 正是基于 WebSocket 來實現(xiàn)的,并且還運用了 Laravel 框架中的隊列、事件等等一系列的功能。在當(dāng)時,我們還要下載一個 larave-echo-server ,大家對這個還有印象不?這個東西也是一個 WebSocket 服務(wù)端,它通過消化 Laravel 中的隊列來實現(xiàn) WebSocket 的消息發(fā)送。 在 Swoole 中,搭建起一個 WebSocket 服務(wù)非常簡單,話不多說,我們直接就搭建起來看看吧。 服務(wù)端對于服務(wù)端來說,WebSocket 服務(wù)也是繼承自 Server 對象的,所以它的大部分方法都差不多,同樣我們也是需要像 TCP 一樣去監(jiān)聽一些事件的。 在 WebSocket 中,監(jiān)聽的主要是 Open 建立連接、Message 消息推送和 Close 連接關(guān)閉的事件。 當(dāng)我們的客戶端連接到服務(wù)時,就會觸發(fā) Open 監(jiān)聽,其中在 $request 中會返回連接的 fd 信息,這是一個句柄,或者說是標(biāo)識我們的客戶端的一個標(biāo)志。然后我們在 Open 監(jiān)聽中每隔十秒去發(fā)送一條消息,假裝是一個后臺的通知信息。 注意,在這里我們不是直接使用 PHP 的那個 sleep() 函數(shù),為什么呢?因為在 Swoole 應(yīng)用中,sleep() 這一類的原生函數(shù)會直接暫停整個進(jìn)程的執(zhí)行,在暫停的過程中,是無法接收到任何請求消息的,不管你是進(jìn)程、線程還是協(xié)程,都會暫停住。而我們監(jiān)聽的事件,實際上是在事件內(nèi)部開了不同的協(xié)程來處理請求的。所以,我們應(yīng)該使用 Coroutine::sleep() 這個 Swoole 提供的休眠函數(shù),它會只針對當(dāng)前的協(xié)程進(jìn)行休眠。 當(dāng)然,你可以嘗試一下使用普通的 sleep() ,你也能正常接收到 push() 的信息,但是,我們后面監(jiān)聽 Message 這一塊的內(nèi)容你可能就無法測出來了。我們馬上來說這 Message 的監(jiān)聽。 它主要監(jiān)聽的是客戶端發(fā)來的信息,當(dāng)接收到客戶端發(fā)來的信息后,我們直接打印信息,并將客戶端發(fā)來的信息再返回給客戶端表示我們收到信息了。 最后,在連接關(guān)閉的時候會監(jiān)聽到 Close 事件中。 整個 WebSocket 最核心的內(nèi)容就是監(jiān)聽這三個事件?,F(xiàn)在你可以在測試環(huán)境中將服務(wù)運行起來了。我們馬上再來寫前端代碼實現(xiàn)客戶端。 前端對于客戶端來說,我們也使用最基礎(chǔ)的原生 JS 中的 WebSocket 寫法來測試。 在這個頁面中,定義了一個文本輸入框和一個按扭用于發(fā)送消息給服務(wù)端。另外下面還有一個 p 標(biāo)簽用于顯示服務(wù)端的消息內(nèi)容。 在 JS 代碼中,我們直接使用的就是原生的 WebSocket 對象。它同樣是需要監(jiān)聽三個主要的方法,和服務(wù)端也是一一對應(yīng)的,分別就是 onopen()、onclose() 和 onmessage() 方法。另外還有一個 send() 方法是上面的按扭調(diào)用的,當(dāng)點擊按扭后,將文本輸入框中的內(nèi)容通過 WebSockent 的 send() 方法發(fā)送給服務(wù)端。 這個頁面運行起來是這個樣子的。
正常情況下現(xiàn)在已經(jīng)建立起了和服務(wù)端的 WebSocket 通信,所以在按扭下方的 p 標(biāo)簽中會有內(nèi)容一直在打印出來。我們可以在文本框中輸入文字,馬上就能看到輸入的文字信息被返回回來了。
總結(jié)怎么樣,還是比較簡單吧,我們非常輕松地就搭起來了一個 WebSocket 服務(wù)?,F(xiàn)在還是在入門學(xué)習(xí)階段,所以東西還比較簡單,不過話說回來,確實在官方文檔上對于這些服務(wù)也沒什么太多的內(nèi)容,畢竟核心的確實就是去監(jiān)聽幾個事件就好了,其它的工作框架在底層都幫我們解決好了。 好吧,沒法去研究底層,畢竟自己的 C/C++ 水平也就僅限于寫個冒泡的水平了(也不一定能寫出來了...)。不過沒關(guān)系,我們一起加油,至少要把 Swoole 的基礎(chǔ)應(yīng)用都掌握好了,而且今天我們又發(fā)現(xiàn)了一個問題,那就是普通的 sleep() 函數(shù)在 Swoole 中的使用是會有問題的,這不也就是一種收獲嘛。 測試代碼: https://github.com/zhangyue0503/swoole/blob/main/2.%E5%9F%BA%E7%A1%80/source/2.4WebSocket%E6%9C%8D%E5%8A%A1.php https://github.com/zhangyue0503/swoole/blob/main/2.%E5%9F%BA%E7%A1%80/source/2.4WebSocket%E5%89%8D%E7%AB%AF.html 參考文檔: https://wiki./#/start/start_ws_server |
|
|