站長資訊網
        最全最豐富的資訊網站

        Laravel 之 廣播 模塊詳解

        本文是基于Laravel 5.4版本的廣播模塊代碼進行分析書寫;

        推薦:《laravel教程》

        簡介

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

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

        ● 公共頻道public

        ● 私有頻道private

        ● 存在頻道presence

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

        廣播適合以下場景(此小部分摘自基于 Pusher 驅動的 Laravel 事件廣播(上)):

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

        通知是最簡單的示例,也最經常用到。信號也可看作是通知的一種展現形式,只不過信號沒有UI而已。

        ● Activity Streams

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

        ● 聊天

        聊天信息的實時顯示

        模塊組成

        Laravel 之 廣播 模塊詳解

        Demo

        日志驅動

        配置

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

        廣播

        直接調用

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

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

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

        監聽事件廣播

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

        舉個例子,

        第一步,IlluminateAuthEventsLogin事件是用戶登錄成功后會觸發的事件,略作改動,讓其實現廣播功能;

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

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

        protected $listen = [    ......    'IlluminateAuthEventsLogin' => [         'AppListenersUserLogin',    ], ];

        文件app/Listeners/UserLogin.php粗糙地實現了一下:

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

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

        1.直接事件觸發

        event(new IlluminateAuthEventsLogin($user, true));

        2.幫助函數broadcast,間接觸發事件

        broadcast(new IlluminateAuthEventsLogin($user, true));

        3.廣播管理類,間接觸發事件,直接廣播

        $manager = app(IlluminateBroadcastingBroadcastManager::class); $manager->event(new IlluminateAuthEventsLogin($user, true));

        4.廣播管理類,間接觸發事件,放入隊列

        $manager = app(IlluminateBroadcastingBroadcastManager::class); $manager->queue(new IlluminateAuthEventsLogin($user, true));

        Pusher驅動

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

        配置

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

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

        準備工作

        事件監聽

        后臺的事件監聽還是采用"日志驅動"部分的登錄例子;

        前端

        前端頁面引入以下代碼:

        <script src="https://js.pusher.com/4.1/pusher.min.js"></script> <script> // 打開 Pusher 的調試日志 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>

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

        頻道權限定義

        頻道的權限定義是在routes/channels.php里;此處筆者為first-channel頻道定義權限回調函數:

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

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

        廣播

        直接廣播

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

        間接廣播

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

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

        1.事件使用IlluminateBroadcastingInteractsWithSockets trait;

        2.前端發送過來的請求頭部要攜帶X-Socket-ID信息;

        3.事件觸發執行broadcast(new IlluminateAuthEventsLogin($user, true))->toOthers();

        Redis驅動

        配置

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

        廣播

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

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

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 久久99精品久久久久久野外 | 蜜臀久久99精品久久久久久小说| 国产精品青草久久久久婷婷| 亚洲а∨天堂久久精品| 午夜精品美女写真福利| 精品亚洲国产成AV人片传媒| 四虎影视永久在线精品| 99热精品久久只有精品| 国产精品扒开腿做爽爽爽视频| 亚洲精品字幕在线观看| 精品无人区无码乱码毛片国产| 欧美亚洲国产精品久久蜜芽| 精品国产福利在线观看| 亚洲精品tv久久久久久久久久| 国产精品综合久成人| 91精品国产色综久久| 国产精品黄网站| 99精品视频在线| 国产l精品国产亚洲区在线观看| 无码人妻精品一区二区三| 亚洲一级Av无码毛片久久精品| 欧洲精品一区二区三区在线观看 | 99在线精品视频在线观看| 亚洲国产精品久久电影欧美| 欧美日韩成人精品久久久免费看| 国产精品伊人久久伊人电影 | 国产亚洲精品精华液| 日本午夜精品一区二区三区电影| 在线成人精品国产区免费| 免费精品精品国产欧美在线欧美高清免费一级在线 | 亚洲精品在线观看视频| 国产一精品一av一免费爽爽| 97精品国产福利一区二区三区| 国产三级精品三级在线专区1 | 日韩精品在线一区二区| 国产精品影音先锋| 九九在线精品视频专区| 四虎最新永久在线精品免费| 91精品久久久久久无码| 国产韩国精品一区二区三区| 国产精品秘入口福利姬网站 |