• 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},说明广播成功。
  • 相关阅读:
    HihoCoder1371
    Intern Day23
    腾讯移动客户端开发暑期实习一面笔试
    C++
    朱丹为什么是文艺青年
    金数据一个不错的调查平台
    单反手动对焦M档,AV,TV,P,A,A-DEP
    chrome不支持字体12px
    火狐解决字体模糊
    《程序员的自我修养》阅读笔记(四):
  • 原文地址:https://www.cnblogs.com/sgm4231/p/9820841.html
Copyright © 2020-2023  润新知