使用 Laravel 廣播事件實現基於 Socket.io 的實時訊息通知

一葉知秋發表於2017-12-04

本文將基於 Laravel 5.5 + Vuejs 2.5.2 介紹使用 Laravel-echo-server.jsLaravel-echo.js 實現的 socket 服務

前置條件

開始使用

  • 指定事件廣播驅動
    修改.env 配置項 BROADCAST_DRIVERredis

  • 建立訊息通知

    確保 User Model 使用了 Notifiable 的 Trait

    php artisan make:notification TestNotification

  • 編輯 TestNotification

    修改 via 方法 return ['broadcast']

    因為 toArray 會同時被解析到 database , 而我們的通知可能和資料庫中的儲存不太一樣,所以單獨使用其 broadcast

    增加 toBroadcast 方法

    public function toBroadcast($notifiable)
    {
        return new BroadcastMessage([
            'message' => $this->data['message']
        ]);
    }

    完整的程式碼如下

    class Test extends Notification implements ShouldQueue
        {
                use Queueable;
    
                public $data;
    
                public function __construct($data = [])
                {
                        $this->data = $data;
                }
    
                public function via($notifiable)
                {
                        return ['broadcast'];
                }
    
                public function toBroadcast($notifiable)
                {
                        return new BroadcastMessage([
                                'message' => $this->data['message']
                        ]);
                }
        }
  • 安裝 socket 服務端
    npm install -g laravel-echo-server
    安裝完成後,在專案根目錄執行 laravel-echo-server init 生成配置檔案 , 具體參考 Laravel-echo-server
    最後,生成的檔案大概類似:

    {
    "authHost": "http://sickle.dev",
    "authEndpoint": "/broadcasting/auth",
    "database": "redis",
    "databaseConfig": {
        "redis": {
            "port" : "6379",
            "host" : "127.0.0.1",
            "db" : 5
        },
        "sqlite": {
            "databasePath": "/database/laravel-echo-server.sqlite"
        }
    },
    "devMode": true,
    "host": null,
    "port": "6001",
    "protocol": "http",
    "socketio": {},
    "sslCertPath": "",
    "sslKeyPath": "",
    "sslCertChainPath": "",
    "sslPassphrase": "",
    "apiOriginAllow": {
        "allowCors": true,
        "allowOrigin": "http://localhost:1024",
        "allowMethods": "GET, POST",
        "allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
    }
    }

    可以參考我的配置,其中 authHost 為你當前專案的域名,allowOrigin 為允許跨域的域名,開發時建議設成 * 號

最後,執行 laravel-echo-server start 開啟 socket 服務端

以下為前端部分

  • 安裝 echo 客戶端

為簡單起見,我們使用一個第三方 vuevue-echo
main.js 裡匯入這個包

import Echo from 'vue-echo'
if(typeof io === 'function'){
    Vue.use(Echo, {
        broadcaster: 'socket.io',
        host: 'service.dev:6001',// 後端的URL + Laravel-echo-server 配置的埠號
        auth:{
            headers: {
                'Authorization': 'Bearer ' + getToken() // getToken前端自行實現
            }
        },
    });
}

在使用之前,最好將使用 socket 服務作為可選項。

然後,開啟監聽

if(typeof this.$echo !== 'undefined'){
    this.$echo.private(`App.Models.User.${this.user_info.user_id}`) //App.Models.User.1
    .notification((notification) => {
        if (notification.type === 'App\\Notifications\\TestNotification') { 
        console.log(notificaition) 
            let message = notification.message;
            let notify = this.$notify({
                title: '通知',
                dangerouslyUseHTMLString: true,
                message: message,
                type: 'info',
                onClick: () => {
                    notify.close();
                    this.$router.push({ name: 'xx' }) // 處理跳轉到哪
                }
            });
        }
        })
}

如果不出意外,此時,已經可以監聽到了。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章