пользователей: 30398
предметов: 12406
вопросов: 234839
Конспект-online
РЕГИСТРАЦИЯ ЭКСКУРСИЯ

События на стороне сервера

33-35. События

Введение

События в Laravel представлены реализацией паттерна Observer, что позволяет вам подписываться и прослушивать события вашего приложения. Как правило, классы событий находятся в папке app/Events, а классы обработчиков событий — в app/Listeners.

Регистрация событий / слушателей

Сервис-провайдер EventServiceProvider, включённый в ваше Laravel приложение, предоставляет удобное место для регистрации всех слушателей событий. Свойство listen содержит массив всех событий (ключей) и их слушателей (значения). Конечно, вы можете добавить столько событий в этот массив, сколько требуется вашему приложению. Например, давайте добавим событие PodcastWasPurchased:

/**

 * Слушатель события в вашем приложении.

 *

 * @var array

 */

protected $listen = [

  'App\Events\PodcastWasPurchased' => [

    'App\Listeners\EmailPurchaseConfirmation',

  ],

];

Генерация классов событий / слушателей

Конечно, вручную создавать файлы для каждого события и слушателя затруднительно. Вместо этого добавьте слушателей и события в ваш EventServiceProvider и используйте команду event:generate. Эта команда сгенерирует все события и слушателей, которые перечислены в вашем EventServiceProvider.
Конечно, уже существующие события и слушатели останутся нетронутыми:

php artisan event:generate

Регистрация событий вручную

Как правило, события должны регистрироваться через массив $listen EventServiceProvider. Однако, также вы можете регистрировать события вручную с обработчиком событий, используя либо фасад Event, либо реализацию контракта Illuminate\Contracts\Events\Dispatcher

/**

 * Регистрация своих событий в приложении.

 *

 * @param  \Illuminate\Contracts\Events\Dispatcher  $events

 * @return void

 */

public function boot(DispatcherContract $events)

{

  parent::boot($events);



  $events->listen('event.name', function ($foo, $bar) {

    //

  });

}

Слушатели событий по маске

Вы даже можете регистрировать слушателей, используя символ *, что позволит вам поймать несколько событий для одного слушателя. Такой метод вернёт весь массив данных событий одним параметром:

$events->listen('event.*', function (array $data) {

  //

});

Определение событий

Класс события — это просто контейнер данных, содержащий информацию, которая относится к событию. Например, предположим, что наше сгенерированное событие PodcastWasPurchased принимает объект Eloquent ORM:

<?php



namespace App\Events;



use App\Podcast;

use App\Events\Event;

use Illuminate\Queue\SerializesModels;



class PodcastWasPurchased extends Event

{

  use SerializesModels;



  public $podcast;



  /**

   * Создание нового экземпляра события.

   *

   * @param  Podcast  $podcast

   * @return void

   */

  public function __construct(Podcast $podcast)

  {

    $this->podcast = $podcast;

  }

}

Как видите, этот класс события не содержит функционала. Это просто контейнер для объекта Podcast. Типаж SerializesModels, используемый событием, корректно сериализирует любые Eloquent модели, если объект события будет сериализирован php-функцией serialize().

Определение слушателей

Теперь давайте взглянем на слушателя для нашего примера события. Слушатели событий принимают экземпляр события в свой метод handle(). Команда event:generate автоматически импортирует класс события и указывает тип события в метод handle(). В методе handle() вы можете выполнять любую логику, необходимую для ответа на событие.

<?php



namespace App\Listeners;



use App\Events\PodcastWasPurchased;

// для версии 5.1 и ранее:

// use Illuminate\Queue\InteractsWithQueue;

// use Illuminate\Contracts\Queue\ShouldQueue;



class EmailPurchaseConfirmation

{

  /**

   * Создание слушателя события.

   *

   * @return void

   */

  public function __construct()

  {

    //

  }



  /**

   * Обработка события.

   *

   * @param  PodcastWasPurchased  $event

   * @return void

   */

  public function handle(PodcastWasPurchased $event)

  {

    // Доступ к podcast, используя $event->podcast...

  }

}

Ваши слушатели события могут также указывать тип любых зависимостей, которые необходимы для их конструкторов. Все слушатели события доступны через сервис-контейнер Laravel, поэтому зависимости будут инъецированы автоматически:

use Illuminate\Contracts\Mail\Mailer;



public function __construct(Mailer $mailer)

{

  $this->mailer = $mailer;

}

Остановка распространения события

Иногда, вам необходимо остановить распространение события для других слушателей. Вы можете сделать это, возвратив false из метода handle() вашего слушателя.

Слушатели события в очереди

Необходимо поставить слушателя события в очередь? Проще некуда. Просто добавьте интерфейс ShouldQueue к классу слушателя. Слушателям, сгенерированным Artisan командой event:generate, уже импортирован этот интерфейс в текущее пространство имен. Так что вы можете сразу использовать его:

<?php



namespace App\Listeners;



use App\Events\PodcastWasPurchased;

// для версии 5.1 и ранее:

// use Illuminate\Queue\InteractsWithQueue;

use Illuminate\Contracts\Queue\ShouldQueue;



class EmailPurchaseConfirmation implements ShouldQueue

{

  //

}

Вот и всё! Теперь, когда этого слушателя вызывают для события, он будет автоматически поставлен в очередь диспетчером события, использующим систему очереди Laravel. Если никакие исключения не будут выброшены, когда слушатель выполняется из очереди, то задача в очереди будет автоматически удалена после своего выполнения.

Ручной доступ к очереди

Если вам необходимо получить доступ к базовым методам очереди delete() и release() вручную, вы можете сделать так. Типаж Illuminate\Queue\InteractsWithQueue, который импортирован по умолчанию в сгенерированные слушатели, предоставляет вам доступ к этим методам:

<?php



namespace App\Listeners;



use App\Events\PodcastWasPurchased;

use Illuminate\Queue\InteractsWithQueue;

use Illuminate\Contracts\Queue\ShouldQueue;



class EmailPurchaseConfirmation implements ShouldQueue

{

  use InteractsWithQueue;



  public function handle(PodcastWasPurchased $event)

  {

    if (true) {

      $this->release(30);

    }

  }

}

Запуск событий

Чтобы запустить событие, вы можете использовать фасад Event, передав экземпляр события методу fire(). Метод fire() распространит событие для всех его зарегистрированных слушателей:

<?php



namespace App\Http\Controllers;



use Event;

use App\Podcast;

use App\Events\PodcastWasPurchased;

use App\Http\Controllers\Controller;



class UserController extends Controller

{

  /**

   * Показать профиль заданного пользователя.

   *

   * @param  int  $userId

   * @param  int  $podcastId

   * @return Response

   */

  public function purchasePodcast($userId, $podcastId)

  {

    $podcast = Podcast::findOrFail($podcastId);



    // Логика покупки podcast...



      Event::fire(new PodcastWasPurchased($podcast));

  }

}

Также вы можете использовать глобальную вспомогательную функцию event() для запуска события:

event(new PodcastWasPurchased($podcast));

Широковещательные события

Во многих современных веб-приложениях используются веб-сокеты, чтобы реализовать быстро обновляющиеся пользовательские интерфейсы реального времени. Когда некоторые данные обновлены на сервере, сообщение обычно отправляется по websocket соединению, которое будет обработано клиентом.

Чтобы помочь вам в создании этих типов приложений, Laravel упрощает «передачу» ваших событий по websocket соединению. Широковещательные события Laravel позволяют вам совместно использовать те же имена событий между серверным кодом и клиентской платформой JavaScript.

Конфигурация

Все параметры широковещательных событий находятся в конфигурационном файле config/broadcasting.php. Laravel поддерживает несколько широковещательных драйверов из коробки: Pusher, Redis и драйвер log для локальной разработки и отладки. Пример конфигурации включен для каждого из этих драйверов.

Требования к широковещательным событиям

Следующие зависимости будут необходимы:

  • Pusher: pusher/pusher-php-server ~2.0
  • Redis: predis/predis ~1.0

Требования к очереди

Перед использованием широковещательных событий также вам будет необходимо сконфигурировать и запустить слушателя очереди. Все широковещательные события используют очереди, чтобы не уменьшать время отклика вашего приложения.

Помечаем широковещательные события

Чтобы проинформировать Laravel о том, что заданное событие должно быть широковещательным, реализуйте интерфейс Illuminate\Contracts\Broadcasting\ShouldBroadcast в классе события. Интерфейс ShouldBroadcast требует реализации одного метода: broadcastOn(). Метод broadcastOn() должен возвращать массив «channel» имён, для которого событие должно быть широковещательным:

<?php



namespace App\Events;



use App\User;

use App\Events\Event;

use Illuminate\Queue\SerializesModels;

use Illuminate\Contracts\Broadcasting\ShouldBroadcast;



class ServerCreated extends Event implements ShouldBroadcast

{

  use SerializesModels;



  public $user;



  /**

   * Создание нового экземпляра события.

   *

   * @return void

   */

  public function __construct(User $user)

  {

    $this->user = $user;

  }



  /**

   * Получение каналов, для которых событие должно быть широковещательным.

   *

   * @return array

   */

  public function broadcastOn()

  {

    return ['user.'.$this->user->id];

  }

}

Теперь вам нужно только запустить событие, как вы это обычно делали. Как только событие было запущено, обработчик очереди автоматически передаст широковещательное событие по вашему указанному широковещательному драйверу.

+ 5.1 5.0

добавлено в 5.1 (19.06.2016) 5.0 (08.02.2016)

Переписываем имена широковещательных событий

По умолчанию широковещательное имя события будет полностью определенным именем класса события. Используя класс в качестве примера выше, широковещательное событие было бы App\Events\ServerCreated. Вы можете определить имя широковещательного события, как вам будет удобнее, используя метод broadcastAs():

/**

 * Получить имя широковещательного события.

 *

 * @return string

 */

public function broadcastAs()

{

    return 'app.server-created';

}

Широковещательные данные

Когда событие широковещательное, все его public свойства автоматически сериализированы и передаются вместе с событием, что позволяет вам получить доступ к любым из его общедоступных данных из JavaScript приложения. Например, если у вашего события есть единственное общедоступное свойство $user, которое содержит Eloquent модель, широковещательные данные будут выглядеть так:

{
  "user": {
    "id": 1,
    "name": "Jonathan Banks"
    ...
  }
}

Однако, если вы хотите иметь еще более тщательный контроль над своими широковещательными данными, вы можете добавить к своему событию метод broadcastWith(). Этот метод должен возвращать массив данных, которые вы хотите передать с событием:

/**

 * Получить данные для передачи.

 *

 * @return array

 */

public function broadcastWith()

{

    return ['user' => $this->user->id];

}

+ 5.2

добавлено в 5.2 (08.12.2016)

Настройка широковещательных событий

Настройка имени события

По умолчанию имя широковещательного события — это полное имя класса этого события. Например, если имя класса App\Events\ServerCreated, то событие будет App\Events\ServerCreated. Имя можно изменить, определив метод broadcastAs() в классе события:

/**

 * Получение имени широковещательного события.

 *

 * @return string

 */

public function broadcastAs()

{

  return 'app.server-created';

}

Настройка очереди

По умолчанию каждое широковещательное событие помещается в очередь по умолчанию для подключения по умолчанию в вашем файле настроек queue.php. Можно изменить очередь для вещания событий, добавив метод onQueue() в класс события. Этот метод должен возвращать имя нужной очереди:

/**

 * Задание имени очереди для размещения событий.

 *

 * @return string

 */

public function onQueue()

{

  return 'your-queue-name';

}

Использование широковещательных событий

Pusher

Вы можете удобно использовать широковещательную передачу событий, используя драйвер Pusher, используя Pusher SDK JavaScript. Например, давайте используем событие App\Events\ServerCreated из наших предыдущих примеров:

this.pusher = new Pusher('pusher-key');



this.pusherChannel = this.pusher.subscribe('user.' + USER_ID);



this.pusherChannel.bind('App\\Events\\ServerCreated', function(message) {

  console.log(message.user);

});

Redis

Если вы будете использовать Redis, то вы должны будете написать свой собственный Redis потребитель типа издатель-подписчик, чтобы получать сообщения и широковещательно передавать их, используя websocket технологию на ваш выбор. Например, вы можете воспользоваться популярной библиотекой Socket.io, которая написана на Node.

Используя библиотеки Node socket.io и ioredis, вы можете быстро написать broadcaster событий, чтобы публиковать все события, которые широковещаются вашим приложением Laravel:

var app = require('http').createServer(handler);

var io = require('socket.io')(app);



var Redis = require('ioredis');

var redis = new Redis();



app.listen(6001, function() {

  console.log('Server is running!');

});



function handler(req, res) {

  res.writeHead(200);

  res.end('');

}



io.on('connection', function(socket) {

  //

});



redis.psubscribe('*', function(err, count) {

  //

});



redis.on('pmessage', function(subscribed, channel, message) {

  message = JSON.parse(message);

  io.emit(channel + ':' + message.event, message.data);

});

Подписчики событий

Подписчики событий — это классы, которые могут подписаться на множество событий из самого класса, что позволяет вам определить несколько обработчиков событий в одном классе. Подписчики должны определить метод subscribe(), в который будет передан экземпляр диспетчера события:

<?php



namespace App\Listeners;



class UserEventListener

{

  /**

   * Обработка события входа пользователя в систему.

   */

  public function onUserLogin($event) {}



  /**

   * Обработка события выхода пользователя из системы.

   */

  public function onUserLogout($event) {}



  /**

   * Регистрация слушателей для подписки.

   *

   * @param  Illuminate\Events\Dispatcher  $events

   */

  public function subscribe($events)

  {

    $events->listen(

      'App\Events\UserLoggedIn',

      'App\Listeners\UserEventListener@onUserLogin'

    );



    $events->listen(

      'App\Events\UserLoggedOut',

      'App\Listeners\UserEventListener@onUserLogout'

    );

  }



}

Регистрация слушателей для подписки

Когда подписчик определён, он может быть зарегистрирован в диспетчере события. Вы можете зарегистрировать подписчиков, используя свойство $subscribe в EventServiceProvider. Например, давайте добавим UserEventListener.

<?php



namespace App\Providers;



use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;



class EventServiceProvider extends ServiceProvider

{

  /**

   * Слушатель события для приложения.

   *

   * @var array

   */

  protected $listen = [

    //

  ];



  /**

   * Классы подписчиков для регистрации.

   *

   * @var array

   */

  protected $subscribe = [

    'App\Listeners\UserEventListener',

  ];

}

+ 5.1 5.0

добавлено в 5.1 (19.06.2016) 5.0 (08.02.2016)

События фреймворка

Laravel предоставляет множество «базовых» событий для действий, выполняемых фреймворком. Вы можете подписаться на них таким же образом, как вы подписываетесь на свои собственные события:

Событие

Параметр(ы)

artisan.start

$application

auth.attempt

$credentials, $remember, $login

auth.login

$user, $remember

auth.logout

$user

cache.missed

$key

cache.hit

$key, $value

cache.write

$key, $value, $minutes

cache.delete

$key

connection.{name}.beganTransaction

$connection

connection.{name}.committed

$connection

connection.{name}.rollingBack

$connection

illuminate.query

$query, $bindings, $time, $connectionName

illuminate.queue.after

$connection, $job, $data

illuminate.queue.failed

$connection, $job, $data

illuminate.queue.stopping

null

mailer.sending

$message

router.matched

$route, $request

{view name}

$view

{view name}

$view

 


22.06.2017; 19:50
хиты: 167
рейтинг:0
для добавления комментариев необходимо авторизироваться.
  Copyright © 2013-2024. All Rights Reserved. помощь