使用 Laravel 广播事件实现基于 Socket.io 的实时消息通知
67

本文将基于 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' }) // 处理跳转到哪
                }
            });
        }
        })
}

如果不出意外,此时,已经可以监听到了。

本帖由 Summer 于 10个月前 加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 13

目前还没用过。不知道用在后台什么功能上面。后面折腾下

10个月前

太棒了
等等就來測試

10个月前

还没写完吧?

10个月前

@839891627 一般来说消息的实时通知应用的最多

10个月前

@jacktop 最近太忙。。现在补

10个月前

多谢楼主!

10个月前

请问下大神,这个方法能在小程序里面用吗?用wepy的话?

5个月前

@dptms 当然可以

5个月前

@dptms 小程序参考 wx.connectSocket

5个月前

@jacobsun this.$echo.private(App.Models.User.${this.user_info.user_id}) 那这种写法,在小程序里面应该怎么写呢?vue 有 use Echo 但是小程序里面的 websocket 跟这个不太一样吧?

5个月前

@dptms 小程序的socket没用过,但是方法应该一样。

自定义一个广播,简单的可以用redis的发布订阅功能,然后自定义一个socket server处理redis的消息,然后小程序里正常连接socket server,最后,注意下channel即可

5个月前
张浩浩浩浩

博主~ ,如果使用 Result API 风格设计的时候,1.该怎样写 2.怎么调试呢?不知道后续你有没有更新呐~

4个月前

Laravel-echo-server在服务器怎么部署呢?

1个月前

  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
  请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!