使用 Laravel-echo-server 构建实时应用

file

在我看来,实时通信才是 APP 应用的将来。 Socket 服务通常不是那么容易实现,但是 Laravel Echo 服务改变了这个情况。

在本文中,我将会简要的介绍如何建立一个可以运行的 Socket 服务并且在这个服务上进行事件的广播。(https://github.com/tlaverdure/laravel-echo..., Laravel 的支持文档: https://learnku.com/docs/laravel/5.6/broadcasting#...)

它是完全免费的,你只要运行你自己的 Socket 服务。你也可以使用 Laravel 默认集成的 Pusher ,唯一的缺点是它是有限制的,如果超出限制则需要付费。我更喜欢自己来架构这些东西。

要求:

  • Laravel 框架 (本教程使用了 5.6 版本)
  • Redis 服务
  • 基本的 Laravel 知识

安装 laravel-echo-server

首先我们需要全局安装 laravel-echo-server ,你只需在终端输入下面的命令。

 $ npm install -g laravel-echo-server

安装完成后,打开你的 Laravel 应用,或者新启一个测试项目:

 $ composer create-project --prefer-dist laravel/laravel echo-test

接下来为我们的应用安装 Predis :

 $ composer require predis/predis

安装完成后,切换到项目根目录下,初始化 Socket 服务:

 $ laravel-echo-server init

执行这条命令后,会询问你一些关于 Socket 服务的配置信息,你可以根据自己的情况填写:

file

切记在生产环境中,无论你什么时候使用它,都应该关掉你的开发者模式。

我们可以尝试启动服务,看看它是否正常运行:

$ laravel-echo-server start

输出结果看起来像这样:

file

配置 Laravel 使 Laravel Echo Server 正常工作

打开你的  config/app.php 文件并且取消 BroadcastServiceProvider 在这个 Providers 数组中的注释:

App\Providers\BroadcastServiceProvider::class,

这个 Provider 将会启动广播路由(你或许已经在 routes/channels.php 文件里面已经看到了)

打开 .env  文件,修改  BROADCAST_DRIVER 的值为你在 laravel-echo-server 初始化时定义的值(Redis 或者 Log)。在本教程中我们将使用 Redis 驱动程序。
同时修改  QUEUE_DRIVER 为你喜欢的任何队列驱动程序,在这个示例中你可以轻松的将其更改为 Redis 驱动程序,因为你在前面已经安装并且在运行了。

接下来我们必须安装 Socket.io 客户端和 Laravel-Echo 包,你可以通过以下操作来安装:

$ npm install --save socket.io-client
$ npm install --save laravel-echo

(在运行这个之前你可能需要运行  npm install  来安装 Laravel 及相关依赖)

接下来打开  resources/assets/js/bootstrap.js  文件, 或者你自己的 引入所有 JS 基础代码的 JS 文件。

现在我们要添加启动 Echo 基础服务的代码:

import Echo from 'laravel-echo'

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

现在我们准备在频道上监听消息了!我会在本教程中解释怎么开放频道,接下来开始收听我们的第一个频道:

window.Echo.channel('test-event')
    .listen('ExampleEvent', (e) => {
        console.log(e);
    });

我们通过 JS 代码告诉程序我们订阅了名为 ’test-event' 的频道, 并监听 ‘ExampleEvent’ 事件 (这是事件的类名,你也可以根据你的需要自定义)。

让我们创建这个事件类:

$ php artisan make:event ExampleEvent

这将会在 App/Events 目录下面创建一个叫做 ExampleEvent.php 的事件类
让我们对这个事件类稍作调整使得它能够在我们的 Socket 服务 中能够正常运行,首先确保你的事件类继承于 ShouldBroadcast 接口,就像下面这样;

class ExampleEvent implements ShouldBroadcast

接下来向下滚动找到  broadcastOn  函数,修改它使得我们能够在正确的频道上进行广播:

public function broadcastOn()
{
    return new Channel('test-event');
}

让我们在下面新建一个函数,这样我们才能有一些实例数据:

public function broadcastWith()
{
    return [
        'data' => 'key'
    ];
}

这个函数在事件被调用时调用,它将会把数据返回到你的 Socket 服务中。

现在让我们开始尝试它吧!打开你的 routes/web.php 文件并且新增一个测试路由:

Route::get('test-broadcast', function(){
    broadcast(new \App\Events\ExampleEvent);
});

(有很多种方式来广播 ExampleEvent  类 ,在这个示例中我使用 Laravel 提供的 broadcast() 助手,在我看来这是最简洁的方式)

启动队列监听:

$ php artisan queue:listen --tries=1

浏览器打开一个包含 JS 文件的页面(可以是 Laravel 默认的欢迎页面),这是第一个页面,请不要关闭次页面,我们已经在此页面上订阅了 Socket 服务。

接下来打开另一个页面访问  /test-broadcast ,这将会返回一个空白页面,但是它将会通过你的 ExampleEvent  类广播到你的 Socket 服务上。返回到我们的第一个页面,打开浏览器控制台,应该可以看到类似信息:

file

正如你所看到的,数据通过这种形式展示在我们的客户端。你能输入任意数据通过你的  ExampleEvent 类来广播他们,这些数据可以是新闻更新,页面更新,总浏览量或者更多。

因为我们有在 laravel-echo-server 配置中有设置开发者模式,所以你能看到 Socket 服务上的所有基本信息:

file

现在你已经安装并运行了一个基本的 Socket 服务!但这并不是全部,你可以根据这个来做更多的事情,比如为单个用户提供认证的私有渠道。(当您想广播订单更新或私人消息时)

要做到这一点,我建议你去查看 Laravel 文档了解更多相关的内容。通过这个主题你能做很多事情,让你的应用程序变得更加神奇。你可以在这里找到相应的文档:

Broadcasting - Laravel - The PHP framework for web artisans.laravel.com

其他: 在生产环境中运行

正如我之前所说,你必须在 laravel-echo-server.json 配置文件中禁用开发者模式。 当然在服务器上你可以忽略这个文件,重新初始化它,因为你的主机可能和本地不同。

你还需要保持你的 Socket 服务在你的生产环境中运行,你可以用 Supervisor ,但是我通常使用 PM2  ,它可以方便快速的管理你的服务。 (http://pm2.keymetrics.io/)

这里是我使用 PM2 的 Socket.sh 基本配置:

#!/usr/bin/env bash

laravel-echo-server  start

安装了 PM2 后, 你可以通过 pm2 start socket.sh 命令来启动脚本,运行你的 Socket 服务。

我希望它能够帮助到你。 这篇文章主要介绍的是一些基础知识,接下来我们会继续讨论广播路由的授权和不同的广播频道。

感谢你的阅读!

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://medium.com/@dennissmink/laravel-...

译文地址:https://learnku.com/laravel/t/13101/usin...

本帖已被设为精华帖!
本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 11
yanrui

学习了

3年前 评论

楼主求教下, 我吧广播部署在线上nginx服务器上, 广播不到10秒就崩掉了,请问有什么优化方式么?

3年前 评论
kevin2011 3年前

这个laravel echo server 可以用p2管理吗

3年前 评论
gyp719 2年前
迟早被自己骚死 1年前
GGabriel (作者) 1年前

请教下,前后端分离,写接口的模式 ,这个
npm install --save socket.io-client
npm install --save laravel-echo
是后端安装 还是前端安装?

2年前 评论
wmhello 2年前
gyp719 (作者) 2年前
gyp719 (作者) 2年前
kuangbo 2年前
playmaker 1年前

Channel: laravel_database_test-event // 通道名称变了..
Event: App\Events\ExampleEvent

2年前 评论
小李世界 2年前

发现两个问题 ,如有错误请纠正
1.QUEUE_DRIVER 需要在5.8中写成QUEUE_CONNECTION
2.laravel5.8的config/database.php redis配置默认加上prefix 需要手动注释或者删除

2年前 评论
GalaxyNo_1

能给app提供服务吗

2年前 评论

file
没这效果是怎么回事?

2年前 评论

file,

file,

前端打印没有结果 是怎么回事

2年前 评论
开心Ta爸 1年前
stela 1年前

这几天在搞这个echo-server,说明下额外的一些坑。 1.laravel-server-json 调试的话devMode开启为true,这样的话,你就可以看见 来自客户的订阅和worker发布的信息,帮助调试。 2.config/database.php redis选项下个option.prefix 这个是最坑爹的。之前没有将devmode设置为true的时候,一直抓瞎,反反复复阅读文档,看源代码理思路,调试还是不得解,开了devmode后,就可以发现广播的channel和客户订阅的channel是2个不同的字符串,其中广播的channel有相对于客户端字符串多余的前缀。对比一看就来了灵感,redis设置的prefix干预,通过broadcaston,一路追溯上去,发现 RedisBroadcaster 有个prefix字段,影响了channel名称,于是改下这个就可以了。2种思路:一种改配置文件prefix项,另一种,在appServiceProvider boot中 利用反射修改

2年前 评论
Insua (楼主) 2年前
kuangbo (作者) 2年前
逆天西瓜 2年前
鸡排饭加蛋 2年前
鸡排饭加蛋 2年前
kuangbo (作者) 2年前
playmaker 1年前

file 按照你的写的,控制台没有打印东西。是连接的

file 不对吗?

1年前 评论
开心Ta爸 1年前
lmdfx 1年前
Wright_tw 1年前
claystone 10个月前
seeker-x2y 9个月前
claystone 9个月前

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