下面由Laravel教程欄目給大家介紹laravel-echo-server廣播服務搭建,希望對需要的朋友有所幫助!

動機
目前項目中很多場景采用 Redis 隊列和定時任務來處理執行時間較長的任務,這些任務執行的狀态和執行結果隻能通過前端重新發送請求擷取。
目标
為了優化程式體驗,讓使用者盡可能早的關注到任務執行結果,我們評估了各種方案。為了降低前後端的溝通成本避免重複造輪子,我們決定采用 Laravel 架構内置的廣播功能。
選擇服務
官方推薦采用 pusher 來搭建應用,pusher 的好處是搭建起來非常簡單。但考慮到是國外的服務,存在通路穩定性風險;且目前項目規模較小,于是嘗試自己搭建 Websocket 服務,使用的就是 Laravel 架構官方提到的 tlaverdure/laravel-echo-server 項目。
laravel-echo-server 服務特點
這個項目的使用方法可以直接去他們的 github 頁面 獲得,我們看中的幾點如下:
- 可通過 Redis 的釋出訂閱功能來擷取事件資訊并廣播出去,這點的效率要高于向 pusher 的 HTTP API 發送推送請求;
- 同時相容 pusher 的 HTTP API ,如果一些服務無法通過 Redis 釋出事件,則可以采用這種模式推送事件;
搭建 Websocket 服務
我們一開始使用了 oanhnn/laravel-echo-server 這個鏡像來啟動容器,在調試過程中發現這個服務并不穩定,Node 的服務會在異常時直接退出,這是我們碰到的第一個坑。為了快速解決這個問題,我們再這個鏡像基礎上加入了 supervisor 來負責進行服務程序的退出後重新開機的任務,并做成了我們自己的鏡像。
Redis 訂閱
在試用 Redis 訂閱時,除了正常的資料庫位址和密碼等參數以外,key 字首是我們碰到的又一個坑,對應在 laravel-echo-server 服務中的 檔案中的 keyPrefix 配置項,一開始沒有找到正确的方法,無論怎麼配置都不對。後來發現如果想知道要廣播事件的程式目前的 Redis key 字首是什麼,就在 tinker 中執行以下腳本即可。
# php artisan tinkerconfig('');
Nginx 代理
由于生産環境采用了 HTTPS 協定,是以需要給服務增加證書,但因為我是 Node 小白,沒有 Node 程式使用證書的配置經驗,是以一輪嘗試之後基本上放棄了,之後采用了 Nginx 代理的方式使用證書,經過幾輪嘗試,終于配置成功。
server {
listen port;
server_name your-domain;
ssl on;
ssl_certificate path-to-pem;
ssl_certificate_key path-to-key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location /socket.io {
proxy_pass http://container-name:6002;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}}
私有/出席頻道授權
Laravel 廣播将頻道分為:公共、私有和出席(我可能翻譯的不對,請指正),其中後兩者是需要授權通路。我們需要用到的是私有頻道,隻有經過授權的人才能從前端訂閱我們的事件。這也是我們遇到的一個坑。
經我們觀察和源碼閱讀,發現 laravel-echo 的整體授權過程是:
- 前端程式先向 laravel-echo-server 服務發送一個 HTTP POST 請求;
- laravel-echo-server 根據配置中
和authEndpoint
這兩項,向應用伺服器發送一個 HTTP POST,POST 資料是 channel 名字,同時透傳 header 中的 Authorization 資料;authHost
- laravel-echo-server 會根據應用伺服器的響應來判斷授權結果,如果應用伺服器響應的是非 HTTP 200 狀态,就說明發生了錯誤,授權失敗。
我們在實踐中遇到兩個問題。第一個問題是,我們項目的授權守門邏輯并非 laravel 預設的,是以預設的
Broadcast::routes()
所引入的路由無法直接使用。發現問題後,我們重新加入了我們自己的授權路由,并配置到 的
authEndpoint
配置項中。
另一個問題是,我們沒有采用标準的 RESTFul 協定規則:響應對應的 HTTP Code 來描述錯誤狀态。緻使 laravel-echo-server 即便在授權失敗的時候也不能發現問題并回報給前端程式,情況類似下圖:
遲早還是要還債的…
總結
這個功能開發的,沒有當初想的那麼順利,主要的問題有以下幾點:
- laravel-echo-server 沒有預想的那麼健壯,以後有時間還得找找替代方案,貌似也有用 swoole 做的項目,可以嘗試一下;
- 預先忘記考慮到 SSL 的問題,導緻釋出時臨時處理得手忙腳亂;
- laravel-echo-server 和 laravel-echo 本身都是很小的項目,遇到問題應該優先考慮去分析其代碼減少嘗試的時間。