先附上 github地址

https://github.com/nothing49199/laravel-echo

简介

在很多现代 Web 应用中,WebSockets被用于实现实时更新的用户接口。当一些数据在服务器上
被更新,通常一条消息通过 Websocket 连接被发送给客户端处理。这为我们提供了一个更强大的、更有效的选择来持续拉取应用的更新。

为实现的这样的应用,Laravel 中 通过 Websocket 连接广播事件使开发变得简单。广播 Laravel 事件允许你在服务端和客户端 JavaScript 框架之间共享同一事件名

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

思路

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

配置

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

  1. BROADCAST_DRIVER=redis

广播服务提供者

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

  1. App\Providers\BroadcastServiceProvider::class,

CSRF令牌

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

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

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

Redis

Redis广播需要安装 Predis库

  1. composer require predis/predis

安装Laravel Echo

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

  1. npm install
  2. npm install laravel-echo-server

初始化 laravel-echo-server

  1. laravel-echo-server init
  2. // 是否在开发模式下运行此服务器(y/n) 输入y
  3. ? Do you want to run this server in development mode? (y/N)
  4. // 设置服务器的端口 默认 6001 输入 6001就可以了 或者你想要的
  5. ? Which port would you like to serve from? (6001)
  6. // 想用的数据库 选择 redis
  7. ? Which database would you like to use to store presence channel members? (Use arrow keys)
  8. redis
  9. sqlite
  10. // 这里输入 你的laravel 项目的访问域名
  11. ? Enter the host of your Laravel authentication server. (http://localhost)
  12. // 选择 网络协议 http
  13. ? Will you be serving on http or https? (Use arrow keys)
  14. http
  15. https
  16. // 您想为HTTP API生成客户端ID/密钥吗 N
  17. ? Do you want to generate a client ID/Key for HTTP API? (y/N)
  18. // 要设置对API的跨域访问吗?(y/n)N
  19. Configuration file saved. Run laravel-echo-server start to run server.

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

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

  1. laravel-echo-server start
  2. L A R A V E L E C H O S E R V E R
  3. version 1.4.2
  4. Starting server in DEV mode...
  5. Running at localhost on port 6001
  6. Channels are ready.
  7. Listening for http events...
  8. Listening for redis events...
  9. Server ready!

频道

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

创建事件

  1. php artisan make:event PublicMessageEvent

文件生成目录 app/Events

  1. // 消息内容
  2. public $message;
  3. public function __construct(string $message)
  4. {
  5. $this->message = $message;
  6. }
  7. // 返回一个公共频道 频道名称为push
  8. public function broadcastOn()
  9. {
  10. return new Channel('push');
  11. }
  12. // Laravel 默认会使用事件的类名作为广播名称来广播事件,自定义:
  13. public function broadcastAs()
  14. {
  15. return 'push.message';
  16. }

添加路由

  1. use App\Events\PublicMessageEvent;
  2. Route::get('/echo', function () {
  3. return view('echo');
  4. });
  5. Route::get('/push/{message}', function ($message) {
  6. broadcast(new PublicMessageEvent($message));
  7. })

前端

安装 laravel-echo

  1. npm install laravel-echo

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

  1. import Echo from "laravel-echo"
  2. window.Echo = new Echo({
  3. broadcaster: 'socket.io',
  4. host: window.location.hostname + ':6001'
  5. });

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

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

创建 echo.blade.php

head 中加上

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

编译 js 文件

  1. npm run watch

浏览器访问 项目域名/echo

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

echo 页面 会自动弹出

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

私有频道 PrivateChannel

创建事件

  1. php artisan make:event PrivateMessageEvent

PrivateMessageEvent 中 写入 以下内容

  1. class PrivateMessageEvent implements ShouldBroadcast
  2. {
  3. // 消息内容
  4. public $message;
  5. // 用户
  6. public $user;
  7. public function __construct(User $user, string $message)
  8. {
  9. $this->user = $user;
  10. $this->message = $message;
  11. }
  12. // 创建私有频道
  13. public function broadcastOn()
  14. {
  15. return new PrivateChannel('privatePush.' . $this->user->id);
  16. }
  17. // //Laravel 默认会使用事件的类名作为广播名称来广播事件,自定义:
  18. // public function broadcastAs()
  19. // {
  20. // return 'privatePush.message';
  21. // }
  22. // 控制广播数据:
  23. public function broadcastWith()
  24. {
  25. return ['message' => $this->message,'status' => 'okok'];
  26. }
  27. }

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

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

频道授权

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

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

前端

echo.blade.php 中加入

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

app.js

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

文章参考

laravel-china
laravel-china
laravel学院

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

感谢你的支持,我会继续努力!
扫码打赏,建议金额1-10元