Laravel事件广播

依赖 laravel(predis)、 redis、 nodejs(ioredis,socket.io) 

1、修改config\app.php

providers数组   添加    ‘Illuminate\Broadcasting\BroadcastServiceProvider‘,

2、修改广播驱动方式为 config\broadcasting.php

‘default‘ => env(‘BROADCAST_DRIVER‘, ‘redis‘), 改为redis驱动

使用redis作为php和js的通信方式。

3、配置config\database.php

配置redis服务连接参数

定义一个被广播的事件

<?phpnamespace App\Events;use App\Events\Event;use Illuminate\Queue\SerializesModels;use Illuminate\Contracts\Broadcasting\ShouldBroadcast;use Illuminate\Support\Facades\Session;class MessageBroadcastEvent extends Event implements ShouldBroadcast{    use SerializesModels;    public $users;    public $message = array();    protected $channel;    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct($users, $message, $channel)
    {
        $this->users = $users;

        $this->message = array(            ‘id‘      => $message[‘id‘], 
            ‘title‘   => $message[‘title‘], 
            ‘content‘ => $message[‘content‘], 
            ‘url‘     => $message[‘url‘], 
            ‘time‘    => date(‘m-d H:i:s‘, strtotime($message[‘created_at‘]))
            );

        $this->channel = $channel;
    }    /**
     * Get the channels the event should be broadcast on.
     * 广播到哪个频道
     * @return array
     */
    public function broadcastOn()
    {        return [$this->channel];
    }
}

默认情况下,Event中的所有public属性都会被序列化后广播。上面的例子中就是$users, $message 两个属性。也可以

使用broadcastWith这个方法,明确的指出要广播什么数据。例如:

public function broadcastWith(){
    return [‘message ‘ => $this->message ];
}

Redis和Websocket服务器

依赖的就是redis的sub/pub功能

启动一个node websocket服务器来和client通信,我们使用socket.io

node 服务端代码 保存为 index.js 放在node服务目录

var app = require(‘http‘).createServer(handler);var io = require(‘socket.io‘)(app);var Redis = require(‘ioredis‘);var redis = new Redis(‘6379‘, ‘192.168.10.10‘); //连接redis服务器//监听客户端端口 这里是 6001app.listen(6001, function() {    console.log(‘Server is running!‘);
});function handler(req, res) {
    res.writeHead(200);
    res.end(‘‘);
}

io.on(‘connection‘, function(socket) {    console.log(‘connected‘);
});

redis.psubscribe(‘*‘, function(err, count) {    console.log(count);
});

redis.on(‘pmessage‘, function(subscribed, channel, message) {    console.log(subscribed);    console.log(channel);    console.log(message);

    //发送到客户端的数据
    message = JSON.parse(message);
    io.emit(channel + ‘:‘ + message.event, message.data);
});

客户端代码,只要客户端需要被广播的页面正确引用 node socket.io 模块客户端js文件(自行将这个客户端模块文件放到项目public目录)

<script src="js/socket.io/node_modules/socket.io-client/socket.io.js"></script>//客户端也使用socket.io,测试代码:控制台打印输出

//连接socket服务器
var socket = io(‘http://localhost:6001‘);
socket.on(‘connection‘, function (data) {
    console.log(data);
});

//收听的频道
socket.on(‘channel-{{ Session::get(‘shop‘)->id }}:App\\Events\\MessageBroadcastEvent‘, function(data) {
    //控制台输出广播消息
    console.log(message);
    
    //这里可以根据收到的消息,做一些改变页面结构的工作……
});

//可以收听多个频道
socket.on(‘channel-system:App\\Events\\MessageBroadcastEvent‘, function(data){
    console.log(data);

    //这里可以根据收到的消息,做一些改变页面结构的工作……
});

//控制台输出连接信息
console.log(socket);

项目中触发事件

在控制器或者在路由匿名函数中都可以直接调用广播事件

1、控制器中直接调用

//发送给哪些用户 id 。 这里定义消息接收用户,是在前台用于检测登陆用户是否在这个数组中,存在则做出相应的即时提醒。//注意:其实广播消息都会被发送到对应的频道的。$users = array(1, 2);//这里可以保存发送消息到 messages 表$message = new Message();
$message->title           = ‘您的店铺有一条新销售单‘;
$message->content         = ‘您的店铺有一条新销售单,单号1000000‘;
$message->message_type_id = 1;
$message->status          = 0;
$message->url             = ‘http://www.xxx.com‘;
$message->save();//保存发送用户 到 user_message 表$userMessage = array();
$time    = date("Y-m-d H:i:s");foreach ($users as $user) { 
    $tmp = array(
        ‘created_at‘ =>$time,
        ‘updated_at‘ =>$time,
        ‘user_id‘    =>$user,
        ‘message_id‘ =>$message->id, 
        ‘read‘       =>0
    );
    $userMessage[] = $tmp;
}
UserMessage::insert($userMessage);//广播的频道//我们以店铺id来标识频道,这样前端用户页面也根据店铺id标识来收听自己店铺频道,就能做到店铺广播消息消息只能广播到本店铺用户$channel = ‘channel-‘ . Session::get(‘shop‘)->id; 
//$channel = ‘channel-system‘; //其他频道//$response = event(new MessageBroadcastEvent($users, $message, $channel));Event::fire(new MessageBroadcastEvent($users, $message, $channel)); //这两种方式都可以触发事件

2、路由中直接调用

//示例代码Route::get(‘/event‘, function(){
    Event::fire(new \App\Events\SomeEvent(3));
    return "hello world";
});

使用:

必须开启 node websocket 服务端。我在本机windows下C盘安装node,服务端代码就放在这个目录下,进入cmd

终端,执行命令,node index.js 启动服务端。

打开包含有 socket.io 代码的客户端页面,等待被广播

触发我们的后台广播事件(执行相应的控制器代码)

时间: 2024-11-15 23:26:10

Laravel事件广播的相关文章

Angularjs中的事件广播-浅谈$broadcast,$emit,$on

Angularjs中不同作用域之间可以通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信 介绍: $broadcast的作用是将事件从父级作用域传播至子级作用域,包括自己.格式如下:$broadcast(eventName,args) $emit的作用是将事件从子级作用域传播至父级作用域,包括自己,直至根作用域.格式如下:$emit(eventName,args) $on用于在作用域中监控从子级或父级作用域中传播的事件以及相应的数据.格式如下:$on(event,dat

android点滴之标准SD卡状态变化事件广播接收者的注册

目前最完整的,需要注册的动作匹配如下: IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED); intentFilter.addAction(Intent.ACTION_ME

Angularjs中的事件广播 —全面解析$broadcast,$emit,$on

Angularjs中不同作用域之间可以通过组合使用$broadcast,$emit,$on的事件广播机制来进行通信 介绍: $broadcast的作用是将事件从父级作用域传播至子级作用域,包括自己.格式如下:$broadcast(eventName,args) $emit的作用是将事件从子级作用域传播至父级作用域,包括自己,直至根作用域.格式如下:$emit(eventName,args) $on用于在作用域中监控从子级或父级作用域中传播的事件以及相应的数据.格式如下:$on(event,dat

[spring源码学习]九、IOC源码-applicationEventMulticaster事件广播

一.代码实例 回到第IOC的第七章context部分,我们看源码分析部分,可以看到在spring的bean加载之后的第二个重要的bean为applicationEventMulticaster,从字面上我们知道它是一个事件广播器.在第8和9部分,详细描述了广播器的初始化: 1.查找是否有name为applicationEventMulticaster的bean,如果有放到容器里,如果没有,初始化一个系统默认的放入容器 2.查找手动设置的applicationListeners,添加到applic

VB.net Wcf事件广播(订阅、发布)

这篇东西原写在csdn.net上,最近新开通了博客想把零散在各处的都转移到一处. 一.源起 学WCF有一段时间了,可是无论是微软的WebCast还是其他网上的教程,亦或我购买的几本书中,都没有怎么提到服务器端事件的订阅.(后来购买的一本WCF服务编程中提供了关于订阅和发布的例子) 网上也查了很多,但大部分都没有清楚地讲到这部分内容,有的虽然是讲这部分内容,但也是语焉不详.最重要的部分都没有讲到(也许是因为水平太差,看不懂).而且网上和书上所用的语言都是C#,这让人很恼火,虽然我能使用C#,但总是

JS里关于事件的常被考察的知识点:事件流、事件广播、原生JS实现事件代理

1.JS里面的事件流 DOM2级事件模型中规定了事件流的三个阶段:捕获阶段.目标阶段.冒泡阶段,低版本IE(IE8及以下版本)不支持捕获阶段 捕获事件流:Netscape提出的事件流,即事件由页面元素接收,逐级向下,传播到最具体的元素. 冒泡事件流:IE提出的事件流,即事件由最具体的元素接收,逐级向上,传播到页面. 关于js事件,这里有一篇非常详细的介绍,可以看下:http://www.cnblogs.com/hyaaon/p/4630128.html 2.IE和W3C不同绑定事件解绑事件的方法

node.js接收异步任务结果的两种方法----callback和事件广播

事件广播 发送方调用emit方法,接收方调用on方法,无论发送方或是接收方,都会工作在一个频道 声明了一个模块,用于读取mime.json中的记录 var fs = require('fs'); var events = require('events'); var eventemitter = new events.EventEmitter(); var getmimetype = function (path,eventemitter,suffix) { fs.readFile(path,f

angularJS 事件广播与接收

发送消息: $scope.$emit(name, data) 或者 $scope.$broadcast(name, data); 接收消息: $scope.on(name,function(event,data){ }); 区别: $emit 广播给父controller   $broadcast 广播给子controller broadcast 是从发送者向他的子scope广播一个事件. 这里就是ParentController发送, ParentController 和 ChildContr

Laravel事件Event

适用场景:记录文章浏览量 1 php artisan make:event 事件名 示例: 1 php artisan make:event MyEvent Laravel目录\app\Events已经生成MyEvent.php文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <?php namespace App\Events; use App\Events\Eve