zoukankan      html  css  js  c++  java
  • laravel 事件广播

    Laravel 5.1 之中新加入了事件广播的功能,作用是把服务器中触发的事件通过websocket服务通知客户端,也就是浏览器,客户端js根据接受到的事件,做出相应动作。本文会用简单的代码展示一个事件广播的过程。
    
    依赖:
    
    redis
    nodejs, socket.io
    laravel 5.1

    配置: config/broadcasting.php中,如下配置'default' => env('BROADCAST_DRIVER', 'redis'),,使用redis作为php和js的通信方式。 config/database.php中配置redis的连接。 定义一个被广播的事件: 根据Laravel文档的说明,想让事件被广播,必须让Event类实现一个IlluminateContractsBroadcastingShouldBroadcast接口,并且实现一个方法broadcastOn。broadcastOn返回一个数组,包含了事件发送到的channel(频道)。如下:
    namespace AppEvents;
    
    use AppEventsEvent;
    use IlluminateQueueSerializesModels;
    use IlluminateContractsBroadcastingShouldBroadcast;
    
    class SomeEvent extends Event implements ShouldBroadcast
    {
      use SerializesModels;
    
      public $user_id;
    
      /**
       * Create a new event instance.
       *
       * @return void
       */
      public function __construct($user_id)
      {
        $this->user_id = $user_id;
      }
    
      /**
       * Get the channels the event should be broadcast on.
       *
       * @return array
       */
      public function broadcastOn()
      {
        return ['test-channel'];
      }
    }
    
    
    被广播的数据:
    默认情况下,Event中的所有public属性都会被序列化后广播。上面的例子中就是$user_id这个属性。你也可以使用broadcastWith这个方法,明确的指出要广播什么数据。例如:
    public function broadcastWith()
    {
      return ['user_id' => $this->user_id];
    }
    
    
    Redis和Websocket服务器:
    需要启动一个Redis,事件广播主要依赖的就是redis的sub/pub功能,具体可以看redis文档
    需要启动一个websocket服务器来和client通信,建议使用socket.io,代码如下:
    
    var app = require('http').createServer(handler);
    var io = require('socket.io')(app);
    
    var Redis = require('ioredis');
    var redis = new Redis('6379', '192.168.1.106');
    
    app.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);
    });
    这里需要注意的是redis.on方法的定义,接收到消息后,给client发送一个事件,事件名称为channel + ':' + message.event。
    
    客户端代码:
    客户端我们也使用socket.io,作为测试,代码尽量简化,仅仅打印一个接受到的数据即可。如下:
    var socket = io('http://localhost:6001');
    socket.on('connection', function (data) {
      console.log(data);
    });
    socket.on('test-channel:App\Events\SomeEvent', function(message){
      console.log(message);
    });
    console.log(socket);
    服务器触发事件:
    直接在router中定义个事件触发即可。如下:
    Route::get('/event', function(){
      Event::fire(new AppEventsSomeEvent(3));
      return "hello world";
    });
    测试:
    
    启动redis
    启动websocket
    打开带有客户端代码的页面,可以看到websocket已经连接成功。
    触发事件,打开另一个页面 localhost/event。
    这时就可以发现,第一个页面的console中打印出了Object{user_id: 3},说明广播成功。
  • 相关阅读:
    《JavaWeb从入门到改行》JSP+EL+JSTL大杂烩汤
    Linux下进程线程,Nignx与php-fpm的进程线程方式
    solr全文检索实现原理
    LSM树以及在hbase中的应用
    MySQL的MyISAM与InnoDB的索引方式
    MySQL的innoDB存储引擎的运作方式,数据结构等
    Redis作缓存
    Redis的几点积累
    Redis数据库各种数据结构的内部实现。
    正则表达式!!!
  • 原文地址:https://www.cnblogs.com/sgm4231/p/9820841.html
Copyright © 2011-2022 走看看