Laravel broadcasting 廣播機制

更新於 發佈於 閱讀時間約 11 分鐘

在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
raw-image
raw-image

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即可:

raw-image

App\Providers\BroadcastServiceProvider預設是被註解的,需打開:

raw-image

新增Event來廣播

假設出貨狀態更新時,我們想要主動通知前端這個訊息,就必須把這個Event廣播出去。

  • 新增一個出貨狀態更新的Event:
$ php artisan make:event ShippingStatusUpdated

將code改成如下:

raw-image
  • 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:

raw-image
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:

raw-image
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>

</head>
<body>

<script src="js/app.js"></script>
<script>
window.Echo.channel('order')
.listen('.OrderUpdated', (e) => {
console.log(e.order);
});
</script>
</body>
</html>
  • 其中<script src="js/app.js"></script>這行就是引用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
raw-image

會在根目錄產生一個laravel-echo-server.json,把devMode改成true方便debug:

raw-image
  • 啟動laravel-echo-server:
$ laravel-echo-server start
raw-image

Demo

raw-image
raw-image

trigger OrderController ship() method,
event(new ShippingStatusUpdated($order)); 這行會觸發event並廣播出去。

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

後記

若發現Channel name多出prefix,可在config/database.php中設定拿掉:

raw-image

laravel_database_就是prefix。

raw-image
  • 將prefix那行註解,就會變成Channel: order。

Laravel Echo listen不到訊息

發現前端一直收不到訊息,解法是將socket.io-client降為安裝2.3.0版本的。(原本裝的是4.5.1)

raw-image

修改package.json後再下npm install即可降版。



本筆記參考:
1. https://docs.laravel-dojo.com/laravel/5.5/broadcasting
2. https://blog.csdn.net/nsrainbow/article/details/80428769
3. https://github.com/tlaverdure/laravel-echo-server
4. https://github.com/tymondesigns/jwt-auth/issues/1577
5. https://github.com/tlaverdure/laravel-echo-server/issues/550



留言
avatar-img
留言分享你的想法!
JASON HYH-avatar-img
2024/06/14
感謝分享, 最近有想玩 Laravel Boardcast 功能, 一直找不到文章; 直到看到這篇才成功
avatar-img
Vic Lin的沙龍
20會員
161內容數
Vic Lin的沙龍的其他內容
2023/08/13
父元件 傳遞方法使用@ <template>    ...    <Login @modalClose="modalClose"/> ... </template> <script setup>     const _modal = ref();     function m
2023/08/13
父元件 傳遞方法使用@ <template>    ...    <Login @modalClose="modalClose"/> ... </template> <script setup>     const _modal = ref();     function m
2023/03/25
前情提要 由於我的筆電已經用了10年,無法再戰下去了,且有預算考量,加上使用電腦幾乎都是定點,只有偶爾回家的時候會需要攜帶,因此最終選擇了迷你電腦,體積小不占空間,又方便攜帶,剛好符合我的需求。 菜單 由於這台無法裝獨顯,所以CPU的部分選擇 AMD R5 3400G(含Vega 11內
Thumbnail
2023/03/25
前情提要 由於我的筆電已經用了10年,無法再戰下去了,且有預算考量,加上使用電腦幾乎都是定點,只有偶爾回家的時候會需要攜帶,因此最終選擇了迷你電腦,體積小不占空間,又方便攜帶,剛好符合我的需求。 菜單 由於這台無法裝獨顯,所以CPU的部分選擇 AMD R5 3400G(含Vega 11內
Thumbnail
2023/03/10
Nuxt3中可使用useFetch來獲取數據,不須再引用axios,相當方便: 本筆記參考: https://juejin.cn/post/7104071421160063012 https://juejin.cn/post/7086472647575339045
2023/03/10
Nuxt3中可使用useFetch來獲取數據,不須再引用axios,相當方便: 本筆記參考: https://juejin.cn/post/7104071421160063012 https://juejin.cn/post/7086472647575339045
看更多
你可能也想看
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
全球科技產業的焦點,AKA 全村的希望 NVIDIA,於五月底正式發布了他們在今年 2025 第一季的財報 (輝達內部財務年度為 2026 Q1,實際日曆期間為今年二到四月),交出了打敗了市場預期的成績單。然而,在銷售持續高速成長的同時,川普政府加大對於中國的晶片管制......
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
重點摘要: 6 月繼續維持基準利率不變,強調維持高利率主因為關稅 點陣圖表現略為鷹派,收斂 2026、2027 年降息預期 SEP 連續 2 季下修 GDP、上修通膨預測值 --- 1.繼續維持利率不變,強調需要維持高利率是因為關稅: 聯準會 (Fed) 召開 6 月利率會議
Thumbnail
本篇純粹紀錄實作流程,以方便未來可以照此版繼續優化改進作法,這篇會使用Laravel 9版本並搭配Boostrap 5來做開發。 發現將每一次的實作作筆記,回頭再看的時候,就可以發現實作差異並進行改正,沒搞懂的底層操作也能在覆盤的時候理解,建議大家都要筆記自己的實作流程。
Thumbnail
本篇純粹紀錄實作流程,以方便未來可以照此版繼續優化改進作法,這篇會使用Laravel 9版本並搭配Boostrap 5來做開發。 發現將每一次的實作作筆記,回頭再看的時候,就可以發現實作差異並進行改正,沒搞懂的底層操作也能在覆盤的時候理解,建議大家都要筆記自己的實作流程。
Thumbnail
What is WebSocket? WebSocket 是 HTML5 提供的一種網路傳輸協定,是瀏覽器(Client)與伺服器(Server)交換資料的方式之一。 與我們較為熟知的 HTTP 或 HTTPS 協定,同樣位於 OSI 模型的應用層,且基於傳輸層的 TCP 協定。
Thumbnail
What is WebSocket? WebSocket 是 HTML5 提供的一種網路傳輸協定,是瀏覽器(Client)與伺服器(Server)交換資料的方式之一。 與我們較為熟知的 HTTP 或 HTTPS 協定,同樣位於 OSI 模型的應用層,且基於傳輸層的 TCP 協定。
Thumbnail
在Laravel中想達到websocket效果,由後端主動傳訊給前端,需使用broadcasting 將event廣播出去,由前端來接收訊息。 因此在業界常看到使用Redis + socket.io的架構,也是本篇選擇的機制。 從伺服器廣播訊息到前端接收的流程,大概會是這樣: 安裝與設定Redis
Thumbnail
在Laravel中想達到websocket效果,由後端主動傳訊給前端,需使用broadcasting 將event廣播出去,由前端來接收訊息。 因此在業界常看到使用Redis + socket.io的架構,也是本篇選擇的機制。 從伺服器廣播訊息到前端接收的流程,大概會是這樣: 安裝與設定Redis
Thumbnail
比如訂單出貨的時候,觸發一個訂單出貨事件,發送出貨email通知給user。 需先註冊event與listener,在EventServiceProvider的$listen中定義: 產生event與listener: 下指令可以方便產生事件與監聽器檔案: 產生的事件與監聽器如下: 事件訂閱者
Thumbnail
比如訂單出貨的時候,觸發一個訂單出貨事件,發送出貨email通知給user。 需先註冊event與listener,在EventServiceProvider的$listen中定義: 產生event與listener: 下指令可以方便產生事件與監聽器檔案: 產生的事件與監聽器如下: 事件訂閱者
Thumbnail
Swoole是一個使用C語言寫出來的PHP extension,本篇筆記了如何使用Laravel+Swoole來打造websocket應用,包含從伺服器安裝到基本範例程式,有websocket基本觀念後,再花點時間,就能把程式改成多人聊天室或私頻聊天等應用了。 Requirement 安裝PHP:
Thumbnail
Swoole是一個使用C語言寫出來的PHP extension,本篇筆記了如何使用Laravel+Swoole來打造websocket應用,包含從伺服器安裝到基本範例程式,有websocket基本觀念後,再花點時間,就能把程式改成多人聊天室或私頻聊天等應用了。 Requirement 安裝PHP:
Thumbnail
Laravel Notifications(通知),是用來通知使用者應用程式訊息的功能,比如付款完成發送email或簡訊通知使用者,文章被訂閱通知等等。Notifications甚至還可以把通知訊息塞進DB,可以用來顯示在後台報表頁面中。 以下以發送email通知來舉例用法。 建立通知 發送通知
Thumbnail
Laravel Notifications(通知),是用來通知使用者應用程式訊息的功能,比如付款完成發送email或簡訊通知使用者,文章被訂閱通知等等。Notifications甚至還可以把通知訊息塞進DB,可以用來顯示在後台報表頁面中。 以下以發送email通知來舉例用法。 建立通知 發送通知
Thumbnail
當伺服器需要處理一些比較花時間的任務時(如發送Email、上傳影片等等),讓user等待直到執行完畢,是個很不明智的選擇,這時候就很適合使用Queue,讓工作在背景執行,使用者就能立刻做下一件事,不必在那邊等待。 .env: QUEUE_CONNECTION預設是sync 改成database:
Thumbnail
當伺服器需要處理一些比較花時間的任務時(如發送Email、上傳影片等等),讓user等待直到執行完畢,是個很不明智的選擇,這時候就很適合使用Queue,讓工作在背景執行,使用者就能立刻做下一件事,不必在那邊等待。 .env: QUEUE_CONNECTION預設是sync 改成database:
Thumbnail
如上篇,使用Migration來做DB版本控制,但是會發現開發過程中若是要建立測試資料,要進DB一筆一筆手動新增或執行預先寫好的insert sql,其實有點麻煩,使用Laravel提供的Seeder功能,就可以解決這個問題。 指令如下,假設建立一個user table seeder:
Thumbnail
如上篇,使用Migration來做DB版本控制,但是會發現開發過程中若是要建立測試資料,要進DB一筆一筆手動新增或執行預先寫好的insert sql,其實有點麻煩,使用Laravel提供的Seeder功能,就可以解決這個問題。 指令如下,假設建立一個user table seeder:
Thumbnail
對於使用Laravel來講,可以直接用composer來安裝predis,可以說是相當方便: config/database.php: redis預設有16個資料庫,這邊是各個資料庫的連接設定。 要使用predis,要記得把env file中的REDIS_CLIENT改成predis。 .env:
Thumbnail
對於使用Laravel來講,可以直接用composer來安裝predis,可以說是相當方便: config/database.php: redis預設有16個資料庫,這邊是各個資料庫的連接設定。 要使用predis,要記得把env file中的REDIS_CLIENT改成predis。 .env:
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News