Запускаем Laravel Echo Server

access_time 2020-04-19 00:31:06

В этой статье, я расскажу как установить и запустить Laravel Echo Server, и создать приложение работающее в реальном времени.

Для работы нам понадобиться:

  1. развёрнутый Laravel проект (у меня версия фреймворка 5.6)
  2. установленный Redis
  3. Хоть какие-то базовые знания Laravel

Как установить и настроить Redis, можно прочитать в моей заметке Установка и настройка Redis на Debian 9.

И так, все исходные данны есть, можно начинать!

Установка Laravel Echo Server

Установим laravel-echo-server через npm глобально:

npm install -g laravel-echo-server

Теперь перейдём в директорию нашего проекта и выполним инициализацию Laravel Echo Server:

laravel-echo-server init

Данная команда поможет создать файл конфигурации laravel-echo-server.json, который появиться в корневой директории вашего проекта. Во время процесса инициализации вам надо будет ответить на несколько вопросов, например для начала, лучше выбрать dev режим, а в качестве базы данных обязательно указать redis. Остальные вопросы разбирать не будем, тк все в принципе понятно. Если что-то не понятно - задавайте вопросы в комментариях.

Теперь, если все хорошо, запускаем:

laravel-echo-server start

Если запуск прошёл успешно, то мы увидем подобное сообщение:

 

laravel-echo-server start

 

А если не успешно? ВНИМАНИЕ! Если вы настроили Redis c использованием пароля (как я рекомендовал в своей статье), то вы получите ошибку:

[ioredis] Unhandled error event: ReplyError: NOAUTH Authentication required.

Это значит, что мы не настроили параметры подключения в файле конфига laravel-echo-server.json. Так что открываем файл конфига, и дополняем его параметрами подключения к Redis:

"databaseConfig": {
		"redis": {
			"port":"6379",
			"host":"127.0.0.1",
			"password":"07d3b02346d294d12e3582dab8b9ed329ab316ed22a19297537377794833defc"
		}
	},

 Сохраняем конфиг и снова запускаем Laravel Echo Server:

laravel-echo-server start

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

Настройка Laravel для работы с Laravel Echo Server

Откройте ваш config/app.php файл и раскомментируйте BroadcastServiceProvider в массиве provider:

App\Providers\BroadcastServiceProvider::class,

Этот провайдер включит широковещательные маршруты.

Откройте .env файл и установите redis в качестве BROADCAST_DRIVER и QUEUE_DRIVER (для работы очередей в laravel мы тоже можем использовать redis).

В .env нам так же надо задать параметры подключения к Redis:

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=07d3b02346d294d12e3582dab8b9ed329ab316ed22a19297537377794833defc
REDIS_PORT=6379

Теперь нам нужно установить клиент socket.io и пакет laravel-echo, вы можете сделать это, выполнив:

npm install --save socket.io-client 
npm install --save laravel-echo

Перед запуском возможно понадобиться выполнить npm install для установки зависимостей.

Все готово! Можно радостно хлопать в ладоши или что вы там обычно делаете когда все получается!

Пример рализации уведомлений в режиме реального времени

Backend

И так, все настроено и готово к работе! Ниже, я покажу как реализовать систему увидомлений, на примере уведомления о новом комментарии в моей блоге. Если у вас недостаточно знаний о событиях и их транслировании в Laravel, настоятельно рекомендую изучить официальную документацию.

Первым делом создадим новое событие выполнив команду:

php artisan make: event CommentAdd

Важно помнить, что наш класс события должен реализовывать интерфейс ShouldBroadcast.

Приведу пример моего класса целиком:

<?php

namespace App\Events;

use App\Comment;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class CommentAdd implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $comment;

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(Comment $comment)
    {
        $this->comment = $comment;
    }

    /**
     * The event's broadcast name.
     *
     * @return string
     */
    public function broadcastAs()
    {
        return 'comment.add';
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new Channel('notification.admin');
    }
}

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

В методе broadcastAs() указываем имя нашего события. Реализовывать этот метод не обязательно, тк по умолчанию, в качестве имени события, Laravel будет использовать имя нашего класса - CommentAdd.

Метод broadcastOn() должен возвращать экземпляр канала, с заданным названием канала.

Существует ещё такой метод как:

public function broadcastWith()
    {
        return [
            'user' => 'test user'
        ];
    }

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

Теперь нам надо вызвать наше событие. У меня для модели комментариев реализован слушатель событий, подробнее можно почитать в официальной документации

Ниже пример реализации вызова события CommentAdd, через слушатель событий модели комментариев:

<?php

namespace App\Observers;

use ...

class CommentObserver
{
    /**
     * Handle the comment "created" event.
     *
     * @param  \App\Comment  $comment
     * @return void
     */
    public function created(Comment $comment)
    {
        event(new CommentAdd($comment));
    }

Тут нас интересует строчка event(new CommentAdd($comment)); именно она отвечает за вызов события CommentAdd, к конструктор которого мы передаём объект комментария. В своём примере вы можете использовать метод event() где хотите. Для примера можно создать маршрут с вызовом события:

Route::get('test-broadcast', function () { 
    event(new \App\Events\ExampleEvent(['foo' => 'bar'])); 
});

Теперь запустим слушатель очереди с помощью artisan команды:

php artisan queue: listen --tries = 1

И вызовем наше событие с помощью метода event() как показано на примере выше. Если все прошло успешно, в консоли мы увидим примерно следующее:

master@s777:~/www/laravel-test.local/site$ php artisan queue:listen --tries=1
[2020-04-18 17:40:40][XUj7c87GIcpoKn6mQNz0xgDCfQGzH4ZC] Processing: App\Events\CommentAdd
[2020-04-18 17:40:40][XUj7c87GIcpoKn6mQNz0xgDCfQGzH4ZC] Processed:  App\Events\CommentAdd

Это значит, что наше событие успешно отправилось в очередь.

Если ваш laravel echo server запущен в dev режиме, то в консоле можно будет увидеть основную информацию о том что происходит на сервере. В данном случае нас интересуют следующие строчки:

Channel: notification.admin
Event: comment.add

Это значит, что все настроили верно. Осталось дело за слушателями этих событий на клиенте.

Frontend

Заключительный этап - реализация слушателей событий на клиенте.

Возможно, вы не знакомы со сборщиками фронтенда в Laravel. В этом случае необходимо ознакомиться с официальном документацией.

Откроем для редактирования файл resources/assets/js/bootstrap.js (в версиях Laravel 5.7 и выше этот файл можно найти по пути resources/js/bootstrap.js).

Запишем базовый код для работы с Echo server:

import Echo from "laravel-echo";

window.io = require('socket.io-client');

window.Echo = new Echo({
    broadcaster: 'socket.io',
    host: window.location.hostname + ':6001'
});

Далее создаём js скрипт с кодом самого слушателя:

window.Echo.channel('notification.admin')
    .listen('.comment.add', (e) => {
        console.log(e);
    });

Данный код говорит о том, что мы подписываемся на канал notification.admin и слушаем событие comment.add, именно такие названия канала и события мы задали в php классе CommentAdd в примерах выше.

Хочу обратить внимание, что в методе broadcastAs класса события CommentAdd мы указали название события без точки в начале "comment.add", а в js коде уже с точкой ".comment.add". Это не ошибка.

Подключите наши js скрипты на любую страницу вашего сайта, например на главную. Теперь повторите вызов события с помощью метода event() как показано на примерах выше.

В консоли браузера (на страницах где подключены наши js скрипты) вы должны увидеть данные которые пришли из события, например как у меня:

Здорово, не правда ли?:)

Кстати, js код слушателя можно немного усовершенствовать, для прослушивания нескольких событий, например:

const channel = window.Echo.channel('notification.admin');

const eventsTolisten = [
    '.comment.add',
    '.comment.delete',
];

eventsTolisten.forEach(event => {
    channel.listen(event, e => {
        console.log(event+':');
        console.log(e);
    })
});

На этом всё! Надеюсь всё понятно. Если остались вопросы или есть предложения и пожелания - пишите комментарии.

Оставить комментарий

Комментарии:

{{ item.user_name }}
access_time 2018-11-01 20:15:22

{{ item.text }}