Laravel broadcasting 廣播機制

閱讀時間約 9 分鐘
在Laravel中想達到websocket效果,由後端主動傳訊給前端,需使用broadcasting 將event廣播出去,由前端來接收訊息。
而想要廣播事件,需要透過driver來廣播,常用的有兩種機制可以選擇:
1. pusher: 有使用限制且須收費
2. Redis + socket.io: 免費無限制
因此在業界常看到使用Redis + socket.io的架構,也是本篇選擇的機制。

  • 從伺服器廣播訊息到前端接收的流程,大概會是這樣:
  1. 使用 Laravel broadcasting(Redis) 廣播 Event 到 Queue(Redis)。
  2. Laravel Queue Listener 讀取Event,並使用Redis的Sub/Pub機制把Event發送給laravel-echo-server。
  3. laravel-echo-server 接收到 Event,並透過socket.io將Event發送给laravel-echo。
  4. laravel-echo解析接收到的 Event。

  • 關於事件廣播的設定檔在這: config/broadcasting.php
pusher/ably/redis/log這些是廣播用的driver,log是在local開發用的。

安裝與設定Redis

若無安裝過predis需先安裝:
$ composer require predis/predis
.env設定:
QUEUE_CONNECTION=redis
BROADCAST_DRIVER=redis
如同上述的流程,QUEUE 與 BROADCAST driver都是選用redis。

註冊BroadcastServiceProvider

在使用廣播之前,需要先註冊BroadcastServiceProvider,在config/app.php 設定檔中找到 providers 陣列,並取消註解App\Providers\BroadcastServiceProvider即可:
App\Providers\BroadcastServiceProvider預設是被註解的,需打開:

新增Event來廣播

假設出貨狀態更新時,我們想要主動通知前端這個訊息,就必須把這個Event廣播出去。
  • 新增一個出貨狀態更新的Event:
$ php artisan make:event ShippingStatusUpdated
將code改成如下:
  • implements ShouldBroadcast是為了當event被觸發時,把event廣播出去。
  • broadcastOn()用來設定要廣播到哪個頻道,如果我們希望只有這個訂單建立者可以查看更新狀態,就要在訂單的私人頻道廣播這個event,如L26註解的。
  • 廣播頻道有三種可以選: Channel/PrivateChannel/PresenceChannel
  • Channel 代表任何使用者都可以訂閱的公共頻道,而 PrivateChannel 和 PresenceChannel 則代表需要授權的私人頻道。
  • broadcastAs()用來自訂廣播名稱。

定義頻道授權規則

  • 如果是用PrivateChannel,需要定義頻道授權規則,如果是公共頻道(Channel)就不用。
  • 在routes/channels.php這邊可以定義頻道授權規則,比如「驗證任何在 order.{orderId} 的私人頻道上嘗試監聽的使用者是否為實際該訂單的建立人」:
Broadcast::channel('order.{orderId}', function ($user, $orderId) {
  return $user->id === Order::findOrNew($orderId)->user_id;
});
  • 注意,如果是用JWT來做認證,需修改BroadcastServiceProvider:
原本是 Broadcast::routes(); 改成:
Broadcast::routes(['middleware' => ['auth:api']]);

自訂廣播名稱:
Laravel 預設會使用Event類別名稱去廣播事件,要自訂廣播名稱需定義broadcastAs() method:
public function broadcastAs()
{
  return 'OrderUpdated';
}

Laravel Echo
  • 安裝:
$ npm install --save socket.io-client
$ npm install --save laravel-echo
resources/js/bootstrap.js最下方有寫好範例程式,去掉註解,改成用socket.io:
import Echo from 'laravel-echo';
window.io = require('socket.io-client');
window.Echo = new Echo({
  broadcaster: 'socket.io',
  host: window.location.hostname + ':6001'
});
build code:
$ npm run dev
  • 會將resources/js build到 public/js(resources/js/app.js => public/js/app.js)
  • 由於app.js中有引用bootstrap.js,所以在頁面中引用app.js就能使用Echo了。
在 resources/views/ 下建立頁面 echo_ex.blade.php:
    
        
        
        
        Laravel
        
    
    
        
        
    
  • 其中這行就是引用public/js/app.js。
  • 這邊值得提的是,listen OrderUpdated前面要多一個「.」,OrderUpdated是對應到broadcastAs()自訂的廣播名稱。
  • Laravel Echo 會需要存取當前 session 的 CSRF token,header中要設定CSRF token。
  • L13~L16就是laravel echo在監聽laravel echo server透過socket.io傳過來的訊息。

Laravel Echo Server
  • 安裝laravel-echo-server:
$ npm install -g laravel-echo-server
  • project根目錄下,初始化laravel-echo-server,所有問題都用預設的:
$ laravel-echo-server init
會在根目錄產生一個laravel-echo-server.json,把devMode改成true方便debug:
  • 啟動laravel-echo-server:
$ laravel-echo-server start

Demo

trigger OrderController ship() method,
event(new ShippingStatusUpdated($order)); 這行會觸發event並廣播出去。
  • 啟動laravel echo server與queue listener,瀏覽器開啟前端,在監聽到event的時候把message print出來。
  • 如上述code,為了簡便,本範例是以廣播至公共頻道來demo,雖然訂單狀態應該是只有建立者可以看的到,需改成私有頻道會較合理。若今天應用情境是新聞推播系統,就很符合範例用的公共頻道。

後記

若發現Channel name多出prefix,可在config/database.php中設定拿掉:
laravel_database_就是prefix。
  • 將prefix那行註解,就會變成Channel: order。

Laravel Echo listen不到訊息

發現前端一直收不到訊息,解法是將socket.io-client降為安裝2.3.0版本的。(原本裝的是4.5.1)
修改package.json後再下npm install即可降版。
為什麼會看到廣告
21會員
161內容數
留言0
查看全部
發表第一個留言支持創作者!
Vic Lin的沙龍 的其他內容
比如訂單出貨的時候,觸發一個訂單出貨事件,發送出貨email通知給user。 需先註冊event與listener,在EventServiceProvider的$listen中定義: 產生event與listener: 下指令可以方便產生事件與監聽器檔案: 產生的事件與監聽器如下: 事件訂閱者
假設有一張表,儲存一個iPhone商品跟剩餘庫存量。 如果商品庫存剩1個,明明是A先買到,這時候就已經沒庫存了,可是系統卻告訴B恭喜你搶到了,這種情況就更糟糕了,只剩下一支iPhone,卻跟兩個人(甚至更多人)都說有買到,也就是發生所謂的超賣問題。 悲觀鎖 Pessimistic Lock
Swoole是一個使用C語言寫出來的PHP extension,本篇筆記了如何使用Laravel+Swoole來打造websocket應用,包含從伺服器安裝到基本範例程式,有websocket基本觀念後,再花點時間,就能把程式改成多人聊天室或私頻聊天等應用了。 Requirement 安裝PHP:
Laravel Notifications(通知),是用來通知使用者應用程式訊息的功能,比如付款完成發送email或簡訊通知使用者,文章被訂閱通知等等。Notifications甚至還可以把通知訊息塞進DB,可以用來顯示在後台報表頁面中。 以下以發送email通知來舉例用法。 建立通知 發送通知
Composer是PHP的軟體包管理系統,它提供用於管理PHP軟體和依賴庫關係的標準格式。(引用自維基百科) composer install composer update 這個指令會更新composer.json中指定的套件版本,比如在require中這樣寫: 但如果是這樣: 本筆記參考:
當伺服器需要處理一些比較花時間的任務時(如發送Email、上傳影片等等),讓user等待直到執行完畢,是個很不明智的選擇,這時候就很適合使用Queue,讓工作在背景執行,使用者就能立刻做下一件事,不必在那邊等待。 .env: QUEUE_CONNECTION預設是sync 改成database:
比如訂單出貨的時候,觸發一個訂單出貨事件,發送出貨email通知給user。 需先註冊event與listener,在EventServiceProvider的$listen中定義: 產生event與listener: 下指令可以方便產生事件與監聽器檔案: 產生的事件與監聽器如下: 事件訂閱者
假設有一張表,儲存一個iPhone商品跟剩餘庫存量。 如果商品庫存剩1個,明明是A先買到,這時候就已經沒庫存了,可是系統卻告訴B恭喜你搶到了,這種情況就更糟糕了,只剩下一支iPhone,卻跟兩個人(甚至更多人)都說有買到,也就是發生所謂的超賣問題。 悲觀鎖 Pessimistic Lock
Swoole是一個使用C語言寫出來的PHP extension,本篇筆記了如何使用Laravel+Swoole來打造websocket應用,包含從伺服器安裝到基本範例程式,有websocket基本觀念後,再花點時間,就能把程式改成多人聊天室或私頻聊天等應用了。 Requirement 安裝PHP:
Laravel Notifications(通知),是用來通知使用者應用程式訊息的功能,比如付款完成發送email或簡訊通知使用者,文章被訂閱通知等等。Notifications甚至還可以把通知訊息塞進DB,可以用來顯示在後台報表頁面中。 以下以發送email通知來舉例用法。 建立通知 發送通知
Composer是PHP的軟體包管理系統,它提供用於管理PHP軟體和依賴庫關係的標準格式。(引用自維基百科) composer install composer update 這個指令會更新composer.json中指定的套件版本,比如在require中這樣寫: 但如果是這樣: 本筆記參考:
當伺服器需要處理一些比較花時間的任務時(如發送Email、上傳影片等等),讓user等待直到執行完畢,是個很不明智的選擇,這時候就很適合使用Queue,讓工作在背景執行,使用者就能立刻做下一件事,不必在那邊等待。 .env: QUEUE_CONNECTION預設是sync 改成database:
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
Simple Storage Service (S3) 是 AWS 最常應用到的服務,只要是需要將檔案上傳到雲端的狀況都可以使用S3,本篇文章將介紹如何設定與使用AWS S3。
Thumbnail
在使用laravel中的Queue job的時候 如果希望job中斷還可以重新啟動這個時候就會需要用到Supervisor了 本篇文章為您帶來如何使用Supervisor執行Laravel的queue:work的教學
Thumbnail
有的時候,會希望在物件導向中對原生的Class新增功能的時候,大多我們都會寫一個新的class並繼承。 但是其實Laravel提供了一個不同的方式,讓我們可以在常用的Class上,直接新增想要的function,那就是macro。
Migration在 Laravel 中是一種用來管理資料庫結構變更的機制。它的主要目的是使開發者能夠在應用程序的不同環境中保持資料庫結構的一致性,並輕鬆地進行結構變更
Thumbnail
待業中後,發現時間變很多就開始東看看西看看,思考著要如何更深入理解Laravel框架的運用,而在Laravel框架中哪些部分是框架替我們做了哪些處理,推薦一個影片給大家一起學習理解。
Thumbnail
一月時,家人聽同事說最近有出一款剝皮辣椒雞碗麵不錯,之後經過711買回來嚐鮮,於是剛好今天就可以開來泡看看啦~ 2021年12月冬季暖心上市 😀
Thumbnail
數位廣告市場持續成長,從 2008 年至今,歷經了兩大浪潮:第一波浪潮為「搜尋廣告」,興起於 2000 年,並至現在仍保持穩定的市場份額;第二波浪潮即是「社群媒體廣告」,於 2010 年起發光發熱、奮力竄起⋯⋯又經過一個 10 年,數位廣告的第三波大浪正在襲來,那就是:零售媒體廣告。
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
11/20日NVDA即將公布最新一期的財報, 今天Sell Side的分析師, 開始調高目標價, 市場的股價也開始反應, 未來一週NVDA將重新回到美股市場的焦點, 今天我們要分析NVDA Sell Side怎麼看待這次NVDA的財報預測, 以及實際上Buy Side的倉位及操作, 從
Thumbnail
Hi 大家好,我是Ethan😊 相近大家都知道保濕是皮膚保養中最基本,也是最重要的一步。無論是在畫室裡長時間對著畫布,還是在旅途中面對各種氣候變化,保持皮膚的水分平衡對我來說至關重要。保濕化妝水不僅能迅速為皮膚補水,還能提升後續保養品的吸收效率。 曾經,我的保養程序簡單到只包括清潔和隨意上乳液
Thumbnail
Simple Storage Service (S3) 是 AWS 最常應用到的服務,只要是需要將檔案上傳到雲端的狀況都可以使用S3,本篇文章將介紹如何設定與使用AWS S3。
Thumbnail
在使用laravel中的Queue job的時候 如果希望job中斷還可以重新啟動這個時候就會需要用到Supervisor了 本篇文章為您帶來如何使用Supervisor執行Laravel的queue:work的教學
Thumbnail
有的時候,會希望在物件導向中對原生的Class新增功能的時候,大多我們都會寫一個新的class並繼承。 但是其實Laravel提供了一個不同的方式,讓我們可以在常用的Class上,直接新增想要的function,那就是macro。
Migration在 Laravel 中是一種用來管理資料庫結構變更的機制。它的主要目的是使開發者能夠在應用程序的不同環境中保持資料庫結構的一致性,並輕鬆地進行結構變更
Thumbnail
待業中後,發現時間變很多就開始東看看西看看,思考著要如何更深入理解Laravel框架的運用,而在Laravel框架中哪些部分是框架替我們做了哪些處理,推薦一個影片給大家一起學習理解。
Thumbnail
一月時,家人聽同事說最近有出一款剝皮辣椒雞碗麵不錯,之後經過711買回來嚐鮮,於是剛好今天就可以開來泡看看啦~ 2021年12月冬季暖心上市 😀
Thumbnail
數位廣告市場持續成長,從 2008 年至今,歷經了兩大浪潮:第一波浪潮為「搜尋廣告」,興起於 2000 年,並至現在仍保持穩定的市場份額;第二波浪潮即是「社群媒體廣告」,於 2010 年起發光發熱、奮力竄起⋯⋯又經過一個 10 年,數位廣告的第三波大浪正在襲來,那就是:零售媒體廣告。