全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Laravel学习教程之广播模块详解

前言

本文主要给大家介绍了关于Laravel广播模块的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍:

注意:本文是基于Laravel 5.4版本的路由模块代码进行分析书写;

简介

广播是指发送方发送一条消息,订阅频道的各个接收方都能及时收到消息;比如 A同学写了一篇文章,这时候 B同学在文章底下评论了,A同学在页面上是不用刷新就能收到提示有文章被评论了,这个本质上就是A同学收到了广播消息,这个广播消息是由B同学评论这个动作触发了发送广播消息;

在整个广播行为中,有一个重要的概念叫频道channel,频道的类型有

  • 公共频道public
  • 私有频道private
  • 存在频道presence

移动端订阅了公共频道public,会直接提示成功;私有频道private和存在频道presence在进行订阅的过程中,会向服务器端发送权限验证,看是不是有权限可以订阅该频道;私有频道private和存在频道presence的区别在于,私有频道private能够接收其他成员发送的消息,而存在频道presence除此之外,还能够在用户的加入与离开时接收信息;

广播适合以下场景:

  • 通知(Notification) 或 信号(Signal)
  • 通知是最简单的示例,也最经常用到。信号也可看作是通知的一种展现形式,只不过信号没有UI而已。
  • Activity Streams
  • Activity Streams(feeds)是社交网络的核心。如微信朋友圈的点赞和评论,A可以实时看到B的点赞,B可以实时看到A的评论。
  • 聊天
  • 聊天信息的实时显示

模块组成


Demo

日志驱动

配置

.env文件修改或添加一行:BROADCAST_DRIVER=log

广播

直接调用

 $manager = app(Illuminate\Broadcasting\BroadcastManager::class);
 $driver = $manager->connection();
 // 第一个参数是频道名,第二个参数是事件名,第三个参数是广播内容
 $driver->broadcast(['channel_1', 'channel_2'], 'login', ['message' => 'hello world']);

因为是日志驱动,所以广播内容会写到框架配置的日志文件中,输出消息如下所示

[2017-08-18 20:45:49] local.INFO: Broadcasting [login] on channels [channel_1, channel_2] with payload:
{
 "message": "hello world"
} 

监听事件广播

这种调用方式,是当实现ShouldBroadcast接口的事件被触发时,则会进行广播操作;(同时,还有一个接口叫ShouldBroadcastNow,与ShouldBroadcast接口的不同在于,将实现ShouldBroadcastNow接口的事件放入队列中时,会被放入叫sync的队列中)

举个例子,

第一步,Illuminate\Auth\Events\Login事件是用户登录成功后会触发的事件,略作改动,让其实现广播功能;

class Login implements ShouldBroadcast {
 ......
 
 // 定义事件被触发时,广播频道;此处定义名为 first-channel 的私有频道
 public function broadcastOn() {
  return [
   new PrivateChannel('first-channel'),
  ];
 }
 
 // 自定义广播名称;如果方法未定义,默认以类名为事件名,此处的默认值是 Illuminate\Auth\Events\Login
 public function broadcastAs() {
  return 'login';
 }
}

第二步,注册事件监听;在app/Providers/EventServiceProvider.php中修改:

protected $listen = [
 ......
 'Illuminate\Auth\Events\Login' => [
  'App\Listeners\UserLogin',
 ],
];

文件app/Listeners/UserLogin.php粗糙地实现了一下:

class UserLogin {
 public function __construct() {}
 
 public function handle(Login $event){
  \Log::info('Do UserLogin Listener: I was Login');
 }
}

第三步,触发事件,发送广播;有好几种触发广播方式:

直接事件触发

event(new Illuminate\Auth\Events\Login($user, true));

帮助函数broadcast,间接触发事件

broadcast(new Illuminate\Auth\Events\Login($user, true));

广播管理类,间接触发事件,直接广播

$manager = app(Illuminate\Broadcasting\BroadcastManager::class);
$manager->event(new Illuminate\Auth\Events\Login($user, true));

广播管理类,间接触发事件,放入队列

$manager = app(Illuminate\Broadcasting\BroadcastManager::class);
$manager->queue(new Illuminate\Auth\Events\Login($user, true));

Pusher驱动

Pusher是一个第三方服务,服务器发送广播时,会向Pusher发送请求,再通过Pusher与浏览器或移动端保持的长连接进行数据交互;

配置

通过Pusher官网注册用户信息,获取属于自已的一套密钥信息,修改.env的配置文件;

BROADCAST_DRIVER=pusher
PUSHER_APP_ID=xxxxxxxxxxxxxxxxxxxxxx
PUSHER_APP_KEY=xxxxxxxxxxxxxxxxxxxxxx
PUSHER_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxx

准备工作

事件监听

后台的事件监听还是采用"日志驱动"部分的登录例子;

前端

前端页面引入以下代码:

<script src="https://js.pusher.com/4.1/pusher.min.js"></script>

<script>
// 打开 Pusher 的调试日志
Pusher.logToConsole = true;

// 定义 Pusher 变量
var pusher = new Pusher('PUSHER_APP_KEY的值', {
 cluster: 'ap1',
 encrypted: true
});

// 定义频道,绑定事件
var channel = pusher.subscribe('private-first-channel');
channel.bind('login', function(data) {
 alert(data);
});
</script>

如果订阅的是公共频道,则不会向服务器端请求权限检查;如果是私有频道(频道名是以private-开头)或存在频道(频道名是以presence-开头),则会发出权限检查请求;对应的后端需要定义私有频道和存在频道的权限;

频道权限定义

频道的权限定义是在routes/channels.php里;此处笔者为first-channel频道定义权限回调函数:

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

有读者会疑问,前端页面订阅的频道不是private-first-channel吗?怎么后端只定义first-channel频道的权限呢?那是因为,后端定义的频道假设是A,那么在Pusher及浏览器端或移动端传递的私有频道名为private-A,存在频道则会是presence-A;

广播

直接广播

$manager = app(Illuminate\Broadcasting\BroadcastManager::class);
$driver = $manager->connection();
// socket 参数是广播私有频道时排除的 socket, 每个浏览器端或者移动端在建立 websocket 时都会被分配一个 socket_id
$driver->broadcast(['private-first-channel'], 'login', ['user' => ['name' => 'hello'], 'socket' => '5395.4377611']);

间接广播

参考“日志驱动”提及的间接广播方式;

如果要发送排我广播(也就是除了当前请求的这个客户端不收到广播消息),则需要以下条件:

  • 事件使用Illuminate\Broadcasting\InteractsWithSockets trait;
  • 前端发送过来的请求头部要携带X-Socket-ID信息;
  • 事件触发执行broadcast(new Illuminate\Auth\Events\Login($user, true))->toOthers();

Redis驱动

配置

.env文件修改或添加一行:BROADCAST_DRIVER=redis

广播

原理是同样在后端部署一个Socket.IO服务器,Laravel框架会发布消息到Socket.IO服务器上,由Socket.IO服务器同浏览器端或者移动端保持长连接;

这部分笔者尚未demo,网上入门资料还是挺多的,知道原理,这部分动作上手就容易多了;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。

附录

同类型的文章可参考以下,加深了解:

  • Laravel学院 事件广播基础知识
  • Pusher 的认识


# laravel  # 模块  # 广播  # 5.4  # Laravel中的Auth模块详解  # Laravel学习教程之View模块详解  # Laravel学习教程之本地化模块  # Laravel学习教程之路由模块  # 基于Laravel实现的用户动态模块开发  # 后端  # 则会  # 会向  # 这部  # 管理类  # 的是  # 是一个  # 是在  # 相关内容  # 第一个  # 就能  # 说了  # 都能  # 是由  # 是指  # 不多  # 也可  # 第二个  # 给大家  # 还有一个 


相关文章: 建站主机选购指南:核心配置与性价比推荐解析  如何用AWS免费套餐快速搭建高效网站?  如何通过服务器快速搭建网站?完整步骤解析  建站之星后台密码遗忘如何找回?  如何用wdcp快速搭建高效网站?  jQuery 常见小例汇总  建站之星代理如何获取技术支持?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  移民网站制作流程,怎么看加拿大移民官网?  企业网站制作公司网页,推荐几家专业的天津网站制作公司?  如何快速配置高效服务器建站软件?  如何在新浪SAE免费搭建个人博客?  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  c++ stringstream用法详解_c++字符串与数字转换利器  高端云建站费用究竟需要多少预算?  建站VPS配置与SEO优化指南:关键词排名提升策略  如何快速生成凡客建站的专业级图册?  高性价比服务器租赁——企业级配置与24小时运维服务  网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?  如何零基础开发自助建站系统?完整教程解析  建站之星安装模板失败:服务器环境不兼容?  历史网站制作软件,华为如何找回被删除的网站?  北京网站制作的公司有哪些,北京白云观官方网站?  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  建站之星安装提示数据库无法连接如何解决?  平台云上自助建站如何快速打造专业网站?  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  如何选择香港主机高效搭建外贸独立站?  网页制作模板网站推荐,网页设计海报之类的素材哪里好?  太平洋网站制作公司,网络用语太平洋是什么意思?  如何零基础在云服务器搭建WordPress站点?  如何快速建站并高效导出源代码?  建站之星如何保障用户数据免受黑客入侵?  营销式网站制作方案,销售哪个网站招聘效果最好?  ,网站推广常用方法?  seo网站制作优化,网站SEO优化步骤有哪些?  专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  建站之星安装后界面空白如何解决?  如何在万网自助建站中设置域名及备案?  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?  网站制作话术技巧,网站推广做的好怎么话术?  如何选择高效便捷的WAP商城建站系统?  如何通过NAT技术实现内网高效建站?  Swift中switch语句区间和元组模式匹配  如何在宝塔面板中修改默认建站目录?  已有域名如何快速搭建专属网站? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。