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
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
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
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
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 年,數位廣告的第三波大浪正在襲來,那就是:零售媒體廣告。