溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Laravel中廣播模塊的示例分析

發(fā)布時間:2021-08-06 09:59:31 來源:億速云 閱讀:122 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要為大家展示了“Laravel中廣播模塊的示例分析”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Laravel中廣播模塊的示例分析”這篇文章吧。

注意:本文是基于Laravel 5.4版本的路由模塊代碼進行分析書寫;

簡介

廣播是指發(fā)送方發(fā)送一條消息,訂閱頻道的各個接收方都能及時收到消息;比如 A同學(xué)寫了一篇文章,這時候 B同學(xué)在文章底下評論了,A同學(xué)在頁面上是不用刷新就能收到提示有文章被評論了,這個本質(zhì)上就是A同學(xué)收到了廣播消息,這個廣播消息是由B同學(xué)評論這個動作觸發(fā)了發(fā)送廣播消息;

在整個廣播行為中,有一個重要的概念叫頻道channel,頻道的類型有

  • 公共頻道public

  • 私有頻道private

  • 存在頻道presence

移動端訂閱了公共頻道public,會直接提示成功;私有頻道private和存在頻道presence在進行訂閱的過程中,會向服務(wù)器端發(fā)送權(quán)限驗證,看是不是有權(quán)限可以訂閱該頻道;私有頻道private和存在頻道presence的區(qū)別在于,私有頻道private能夠接收其他成員發(fā)送的消息,而存在頻道presence除此之外,還能夠在用戶的加入與離開時接收信息;

廣播適合以下場景:

  • 通知(Notification) 或 信號(Signal)

  • 通知是最簡單的示例,也最經(jīng)常用到。信號也可看作是通知的一種展現(xiàn)形式,只不過信號沒有UI而已。

  • Activity Streams

  • Activity Streams(feeds)是社交網(wǎng)絡(luò)的核心。如微信朋友圈的點贊和評論,A可以實時看到B的點贊,B可以實時看到A的評論。

  • 聊天

  • 聊天信息的實時顯示

模塊組成

Laravel中廣播模塊的示例分析

Demo

日志驅(qū)動

配置

.env文件修改或添加一行:BROADCAST_DRIVER=log;

廣播

直接調(diào)用

 $manager = app(Illuminate\Broadcasting\BroadcastManager::class);
 $driver = $manager->connection();
 // 第一個參數(shù)是頻道名,第二個參數(shù)是事件名,第三個參數(shù)是廣播內(nèi)容
 $driver->broadcast(['channel_1', 'channel_2'], 'login', ['message' => 'hello world']);

因為是日志驅(qū)動,所以廣播內(nèi)容會寫到框架配置的日志文件中,輸出消息如下所示

[2017-08-18 20:45:49] local.INFO: Broadcasting [login] on channels [channel_1, channel_2] with payload:
{
 "message": "hello world"
}

監(jiān)聽事件廣播

這種調(diào)用方式,是當(dāng)實現(xiàn)ShouldBroadcast接口的事件被觸發(fā)時,則會進行廣播操作;(同時,還有一個接口叫ShouldBroadcastNow,與ShouldBroadcast接口的不同在于,將實現(xiàn)ShouldBroadcastNow接口的事件放入隊列中時,會被放入叫sync的隊列中)

舉個例子,

第一步,Illuminate\Auth\Events\Login事件是用戶登錄成功后會觸發(fā)的事件,略作改動,讓其實現(xiàn)廣播功能;

class Login implements ShouldBroadcast {
 ......
 
 // 定義事件被觸發(fā)時,廣播頻道;此處定義名為 first-channel 的私有頻道
 public function broadcastOn() {
  return [
   new PrivateChannel('first-channel'),
  ];
 }
 
 // 自定義廣播名稱;如果方法未定義,默認以類名為事件名,此處的默認值是 Illuminate\Auth\Events\Login
 public function broadcastAs() {
  return 'login';
 }
}

第二步,注冊事件監(jiān)聽;在app/Providers/EventServiceProvider.php中修改:

protected $listen = [
 ......
 'Illuminate\Auth\Events\Login' => [
  'App\Listeners\UserLogin',
 ],
];

文件app/Listeners/UserLogin.php粗糙地實現(xiàn)了一下:

class UserLogin {
 public function __construct() {}
 
 public function handle(Login $event){
  \Log::info('Do UserLogin Listener: I was Login');
 }
}

第三步,觸發(fā)事件,發(fā)送廣播;有好幾種觸發(fā)廣播方式:

直接事件觸發(fā)

event(new Illuminate\Auth\Events\Login($user, true));

幫助函數(shù)broadcast,間接觸發(fā)事件

broadcast(new Illuminate\Auth\Events\Login($user, true));

廣播管理類,間接觸發(fā)事件,直接廣播

$manager = app(Illuminate\Broadcasting\BroadcastManager::class);
$manager->event(new Illuminate\Auth\Events\Login($user, true));

廣播管理類,間接觸發(fā)事件,放入隊列

$manager = app(Illuminate\Broadcasting\BroadcastManager::class);
$manager->queue(new Illuminate\Auth\Events\Login($user, true));

Pusher驅(qū)動

Pusher是一個第三方服務(wù),服務(wù)器發(fā)送廣播時,會向Pusher發(fā)送請求,再通過Pusher與瀏覽器或移動端保持的長連接進行數(shù)據(jù)交互;

配置

通過Pusher官網(wǎng)注冊用戶信息,獲取屬于自已的一套密鑰信息,修改.env的配置文件;

BROADCAST_DRIVER=pusher
PUSHER_APP_ID=xxxxxxxxxxxxxxxxxxxxxx
PUSHER_APP_KEY=xxxxxxxxxxxxxxxxxxxxxx
PUSHER_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxx

準(zhǔn)備工作

事件監(jiān)聽

后臺的事件監(jiān)聽還是采用"日志驅(qū)動"部分的登錄例子;

前端

前端頁面引入以下代碼:

<script src="https://js.pusher.com/4.1/pusher.min.js"></script>

<script>
// 打開 Pusher 的調(diào)試日志
Pusher.logToConsole = true;

// 定義 Pusher 變量
var pusher = new Pusher('PUSHER_APP_KEY的值', {
 cluster: 'ap1',
 encrypted: true
});

// 定義頻道,綁定事件
var channel = pusher.subscribe('private-first-channel');
channel.bind('login', function(data) {
 alert(data);
});
</script>

如果訂閱的是公共頻道,則不會向服務(wù)器端請求權(quán)限檢查;如果是私有頻道(頻道名是以private-開頭)或存在頻道(頻道名是以presence-開頭),則會發(fā)出權(quán)限檢查請求;對應(yīng)的后端需要定義私有頻道和存在頻道的權(quán)限;

頻道權(quán)限定義

頻道的權(quán)限定義是在routes/channels.php里;此處筆者為first-channel頻道定義權(quán)限回調(diào)函數(shù):

Broadcast::channel('first-channel', function ($user) {
  return (int) $user->id === 1;
});

有讀者會疑問,前端頁面訂閱的頻道不是private-first-channel嗎?怎么后端只定義first-channel頻道的權(quán)限呢?那是因為,后端定義的頻道假設(shè)是A,那么在Pusher及瀏覽器端或移動端傳遞的私有頻道名為private-A,存在頻道則會是presence-A;

廣播

直接廣播

$manager = app(Illuminate\Broadcasting\BroadcastManager::class);
$driver = $manager->connection();
// socket 參數(shù)是廣播私有頻道時排除的 socket, 每個瀏覽器端或者移動端在建立 websocket 時都會被分配一個 socket_id
$driver->broadcast(['private-first-channel'], 'login', ['user' => ['name' => 'hello'], 'socket' => '5395.4377611']);

間接廣播

參考“日志驅(qū)動”提及的間接廣播方式;

如果要發(fā)送排我廣播(也就是除了當(dāng)前請求的這個客戶端不收到廣播消息),則需要以下條件:

  • 事件使用Illuminate\Broadcasting\InteractsWithSockets trait;

  • 前端發(fā)送過來的請求頭部要攜帶X-Socket-ID信息;

  • 事件觸發(fā)執(zhí)行broadcast(new Illuminate\Auth\Events\Login($user, true))->toOthers();

Redis驅(qū)動

配置

.env文件修改或添加一行:BROADCAST_DRIVER=redis;

廣播

原理是同樣在后端部署一個Socket.IO服務(wù)器,Laravel框架會發(fā)布消息到Socket.IO服務(wù)器上,由Socket.IO服務(wù)器同瀏覽器端或者移動端保持長連接;

這部分筆者尚未demo,網(wǎng)上入門資料還是挺多的,知道原理,這部分動作上手就容易多了;

以上是“Laravel中廣播模塊的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI