Laravel broadcasting 廣播機制

更新於 2022/06/10閱讀時間約 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即可降版。
為什麼會看到廣告
avatar-img
21會員
161內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
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
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
我們在「【Message Queue - Kafka】串流時代的超入門簡介」有介紹到關於Kafka的基礎概念, 那麼本章節主要著重於生產者(Producer)的面向來細部探討, 看看生產者(Producer)究竟是什麼? 有哪些應該要注意的? 我們今天的主題除了說明生產者(Producer)的
Thumbnail
※ 什麼是路由? 當我們說「路由」時,可能是在談論路由器(實體設備),也可能是在談論路由(選擇路徑的過程),或者是在談論路徑(資料封包的傳輸路徑)。 路由器 (Router):這是一種實體設備,負責將資料封包 (Packet) 從一個網路傳送到另一個網路。它的工作方式類似於交通指揮,確保資料封包
Thumbnail
Vue Router 動態路由,假設有一個賣場,裡面有 100 個商品,我們不可能針對它們創 100 對應的路由,因此我們需要一個動態路由,利用"路徑帶參數"的方式來撈取商品的資訊。
Thumbnail
訊息的即時傳遞已然成為現代社會的趨勢了, 而扮演中樞平台的系統架構功能也漸趨複雜完整, Kafka是一個事件流平台, 正好滿足串流時代之下的即時訊息傳遞架構, 因此我們有必要深入來學習這套事件流平台, 不論是自動化、金融交易、IOT、物流…皆離不開即時的需求, 所以就讓我們蹲好馬步來好好的學習一
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
組件之間的通信是 Vue 應用開發中的一個重要方面。Vue 提供了一種名為事件發射(emit)的機制,讓子組件能夠向父組件發送消息。本文將介紹 Vue 中的事件發射(emit)機制,並通過實際範例演示其用法。
Thumbnail
在使用laravel中的Queue job的時候 如果希望job中斷還可以重新啟動這個時候就會需要用到Supervisor了 本篇文章為您帶來如何使用Supervisor執行Laravel的queue:work的教學
Thumbnail
有的時候,會希望在物件導向中對原生的Class新增功能的時候,大多我們都會寫一個新的class並繼承。 但是其實Laravel提供了一個不同的方式,讓我們可以在常用的Class上,直接新增想要的function,那就是macro。
Thumbnail
Websocket是一種網路傳輸的協定,讓建立一次handshake的過程就可以相互傳遞資料,而非同步的過程能夠讓處理事情更有效率,這篇文章將帶你深入瞭解Websocket如何運作、以及其特點與優勢。
Thumbnail
Redis被稱為「資料結構伺服器」,因為其中的值(Value)可以是字串(String)、雜湊(Hash)、清單(List)、集合(Set)和有序集合(Sorted Set)等類型。 安裝 下載 wget https://download.redis.io/release/redis-6.
Thumbnail
徵的就是你 🫵 超ㄅㄧㄤˋ 獎品搭配超瞎趴的四大主題,等你踹共啦!還有機會獲得經典的「偉士牌樂高」喔!馬上來參加本次的活動吧!
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
我們在「【Message Queue - Kafka】串流時代的超入門簡介」有介紹到關於Kafka的基礎概念, 那麼本章節主要著重於生產者(Producer)的面向來細部探討, 看看生產者(Producer)究竟是什麼? 有哪些應該要注意的? 我們今天的主題除了說明生產者(Producer)的
Thumbnail
※ 什麼是路由? 當我們說「路由」時,可能是在談論路由器(實體設備),也可能是在談論路由(選擇路徑的過程),或者是在談論路徑(資料封包的傳輸路徑)。 路由器 (Router):這是一種實體設備,負責將資料封包 (Packet) 從一個網路傳送到另一個網路。它的工作方式類似於交通指揮,確保資料封包
Thumbnail
Vue Router 動態路由,假設有一個賣場,裡面有 100 個商品,我們不可能針對它們創 100 對應的路由,因此我們需要一個動態路由,利用"路徑帶參數"的方式來撈取商品的資訊。
Thumbnail
訊息的即時傳遞已然成為現代社會的趨勢了, 而扮演中樞平台的系統架構功能也漸趨複雜完整, Kafka是一個事件流平台, 正好滿足串流時代之下的即時訊息傳遞架構, 因此我們有必要深入來學習這套事件流平台, 不論是自動化、金融交易、IOT、物流…皆離不開即時的需求, 所以就讓我們蹲好馬步來好好的學習一
Thumbnail
前段時間我們有介紹「【Python 軍火庫🧨 - websockets】雙向溝通的渠道」, 這種方式可以達到基本的連線沒問題,但隨著資安意識的抬頭, 我們的websocket連線也會需要在通道之上進行加密, 那麼我們將根據使用情境來教您如何選用適當的連線。 Server端 我們的Serve
Thumbnail
組件之間的通信是 Vue 應用開發中的一個重要方面。Vue 提供了一種名為事件發射(emit)的機制,讓子組件能夠向父組件發送消息。本文將介紹 Vue 中的事件發射(emit)機制,並通過實際範例演示其用法。
Thumbnail
在使用laravel中的Queue job的時候 如果希望job中斷還可以重新啟動這個時候就會需要用到Supervisor了 本篇文章為您帶來如何使用Supervisor執行Laravel的queue:work的教學
Thumbnail
有的時候,會希望在物件導向中對原生的Class新增功能的時候,大多我們都會寫一個新的class並繼承。 但是其實Laravel提供了一個不同的方式,讓我們可以在常用的Class上,直接新增想要的function,那就是macro。
Thumbnail
Websocket是一種網路傳輸的協定,讓建立一次handshake的過程就可以相互傳遞資料,而非同步的過程能夠讓處理事情更有效率,這篇文章將帶你深入瞭解Websocket如何運作、以及其特點與優勢。
Thumbnail
Redis被稱為「資料結構伺服器」,因為其中的值(Value)可以是字串(String)、雜湊(Hash)、清單(List)、集合(Set)和有序集合(Sorted Set)等類型。 安裝 下載 wget https://download.redis.io/release/redis-6.