Laravel Redis 广播 实例

先附上 github地址

github.com/wanghao-fan/laravel-ech...

本 文中 仅使用了 redis的广播驱动

思路

laravel 的广播系统和队列系统类似,需要两个进程协作,一个是 laravel 的 web 后台系统,另一个是 Socket.IO 服务器系统。具体的流程是页面加载时,网页 js 程序 Laravel Echo 与 Socket.IO 服务器建立连接, laravel 发起通过驱动发布广播,Socket.IO 服务器接受广播内容,对连接的客户端网页推送信息,以达到网页实时更新的目的。

配置

配置文件 config/broadcasting.php,可以直接在 .env 中配置以下代码

BROADCAST_DRIVER=redis

广播服务提供者

config/app.php 配置文件中 providers数组中打开注释

App\Providers\BroadcastServiceProvider::class,

CSRF令牌

Laravel Echo需要访问当前 Session 的 CSRF 令牌(token)

自创建的 blade视图的 head中 加入 meta标签

<meta name="csrf-token" content="{{ csrf_token() }}">

Redis

Redis广播需要安装 Predis库

composer require predis/predis

安装Laravel Echo

Laravel Echo是一个JavaScript库,web端可以轻松订阅频道并收听Laravel广播的事件
通过 npm 包管理器安装 Echo

npm install
npm install -g laravel-echo-server

初始化 laravel-echo-server

laravel-echo-server init

// 是否在开发模式下运行此服务器(y/n) 输入y
? Do you want to run this server in development mode? (y/N) 

// 设置服务器的端口 默认 6001 输入 6001就可以了 或者你想要的
? Which port would you like to serve from? (6001)

// 想用的数据库  选择 redis
? Which database would you like to use to store presence channel members? (Use arrow keys)
❯ redis 
  sqlite 

//   这里输入 你的laravel  项目的访问域名
? Enter the host of your Laravel authentication server. (http://localhost) 

// 选择 网络协议 http
? Will you be serving on http or https? (Use arrow keys)
❯ http 
  https 

// 您想为HTTP API生成客户端ID/密钥吗 N
? Do you want to generate a client ID/Key for HTTP API? (y/N) 

// 要设置对API的跨域访问吗?(y/n)N
Configuration file saved. Run laravel-echo-server start to run server.

设置完成后 项目根目录 下 会生成 laravel-echo-server.json 文件 这里面就是刚才的配置

执行命令启动 服务 出现如下 则启动成功

laravel-echo-server start

L A R A V E L  E C H O  S E R V E R

version 1.4.2

⚠ Starting server in DEV mode...

✔  Running at localhost on port 6001
✔  Channels are ready.
✔  Listening for http events...
✔  Listening for redis events...

Server ready!

频道

频道必须是 Channel、PrivateChannel 或 PresenceChannel 的实例。Channel 实例表示任何用户都可以订阅的公开频道,而 PrivateChannels 和 PresenceChannels 则表示需要 频道授权 的私有频道:

创建事件

php artisan make:event PublicMessageEvent 

文件生成目录 app/Events

// 消息内容
public $message;

public function __construct(string $message)
{
    $this->message = $message;
}

// 返回一个公共频道 频道名称为push
public function broadcastOn()
{
    return new Channel('push');
}

// Laravel 默认会使用事件的类名作为广播名称来广播事件,自定义:
public function broadcastAs()
{
    return 'push.message';
}

添加路由

 use App\Events\PublicMessageEvent;
 Route::get('/echo', function () {
    return view('echo');
 });

Route::get('/push/{message}', function ($message) {
    broadcast(new PublicMessageEvent($message));
})

前端

安装 laravel-echo

npm install laravel-echo

编辑 resource/js/bootstrap.js 添加如下代码

import Echo from "laravel-echo"

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});

编辑 resource/js/app.js 添加如下代码

Echo.channel('push')
.listen('.push.message', (e) => {
    alert('来了')
    console.log(e);
});

创建 echo.blade.php

head 中加上

 <meta name="csrf-token" content="{{ csrf_token() }}">
 <script src="//{{ Request::getHost() }}:6001/socket.io/socket.io.js"></script>

 <script src="/js/app.js"></script>

编译 js 文件

npm run watch

浏览器访问 项目域名/echo

浏览器访问 项目域名/push/这是一个测试广播

echo 页面 会自动弹出

到这 广播 发布到公共频道就完成了

私有频道 PrivateChannel

创建事件

php artisan make:event PrivateMessageEvent

PrivateMessageEvent 中 写入 以下内容

class PrivateMessageEvent implements ShouldBroadcast
{

    // 消息内容
    public $message;
    // 用户
    public $user;

    public function __construct(User $user, string $message)
    {
        $this->user = $user;
        $this->message = $message;
    }

    // 创建私有频道
    public function broadcastOn()
    {
        return new PrivateChannel('privatePush.' . $this->user->id);
    }

    //    //Laravel 默认会使用事件的类名作为广播名称来广播事件,自定义:
    //    public function broadcastAs()
    //    {
    //        return 'privatePush.message';
    //    }

    // 控制广播数据:
    public function broadcastWith()
    {
        return ['message' => $this->message,'status' => 'okok'];
    }
}

添加发布广播到私有频道 触发路由 routes/web

Route::get('/privatePush/{message}/{id}', function ($message, $id) {
    $user = \App\User::find($id);
    if (empty($user)) return '无此用户';
    broadcast(new PrivateMessageEvent($user, $message));
});

频道授权

定义授权路由 routes/channel 中加入一下代码

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

前端

echo.blade.php 中加入

<script>
    @if(!empty(Auth::user()))
        window.id = "{{Auth::user()->id}}"
    @endif
</script>

app.js

Echo.private('privatePush.' + window.id)
.listen('PrivateMessageEvent', (e) => {
    alert('qweqwe')
    console.log(e);
});

我的博客

我的掘金

我的简书

Laravel China

我的微信公众号

本作品采用《CC 协议》,转载必须注明作者和本文链接
安静的美男子
本帖由系统于 6年前 自动加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 12

这个需要全局安装吧?

$  npm install -g laravel-echo-server
6年前 评论

@Johnson16 嗯嗯,确实,这里我写错了,已经改了 ,谢谢你的提醒

6年前 评论

大神,你的文章对我启发很大,感谢,希望您多出一些精品文章,给我们学习!

6年前 评论
张浩浩浩浩

博主,我根据你这个已经测通了。我想问一个问题
laravel-echo-server start 这个怎么才能后台去运行呢,我关闭了 就 io is not a function

L A R A V E L  E C H O  S E R V E R

version 1.5.0

⚠ Starting server in DEV mode...

✔  Running at localhost on port 6001
✔  Channels are ready.
✔  Listening for http events...
✔  Listening for redis events...

Server ready!
6年前 评论

@张浩浩浩浩 最简单的,根目录下 运行 nohup laravel-echo-server start & ,关闭时, 调出 (fg n) ,执行 ctrl + c 终止

6年前 评论
张浩浩浩浩

@安静的美男子 嗯,谢谢。执行nohup laravel-echo-server start & 可以了。发现项目/目录生成了一个nohup.out文件,但是执行完会报一个[vagrant@localhost laravel55]$ nohup: ignoriere Eingabe und hänge Ausgabe an „nohup.out“ an (译:nohup:忽略输入并将输出附加到“nohup.out”) :joy: :joy: :joy:

6年前 评论

如果是小程序或者APP,如何广播消息呢?

5年前 评论

问下,前后端分离 laravel-echo-server 是前端进行 安装吗

5年前 评论

代码 写好了 运行啥反应都没有

5年前 评论
Devin_Booker 4年前

file
大神,这个打出来socket是空的,也没有console出来信息,这个是什么原因呢,

5年前 评论

laravel 前后端分离了,这种方式还能使用吗

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!