Advertisement
  1. Code
  2. PHP

Как работает Laravel Broadcasting

Scroll to top
Read Time: 17 min

Russian (Pусский) translation by Ilya Nikov (you can also view the original English article)

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

Если вы когда-либо хотели отправлять уведомления с сервера клиенту, когда что-то происходит на сервере в Laravel, вам определенно нужна фича broadcasting.

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

Это идеальный use-case, чтобы рассмотреть концепцию трансляции в Laravel, и это то, что мы будем реализовывать в этой статье.

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

  • Во-первых, вам нужен сервер, поддерживающий протокол веб-сокетов и позволяющий клиенту устанавливать соединение с веб-сокетом.
  • Вы можете реализовать свой собственный сервер или использовать стороннюю службу, такую как Pusher. Мы предпочтем последнее в этой статье.
  • Клиент инициирует подключение веб-сокета к серверу веб-сокетов и получает уникальный идентификатор при успешном соединении.
  • Как только соединение будет успешным, клиент подписывается на определенные каналы, по которым он хочет получать события.
  • Наконец, по подписанному каналу клиент регистрирует события, которые он хотел бы прослушать.
  • Теперь на стороне сервера, когда происходит определенное событие, мы сообщаем серверу веб-сокетов, предоставляя ему имя канала и имя события.
  • И, наконец, сервер веб-сокетов передает это событие зарегистрированным клиентам на этом конкретном канале.

Не беспокойтесь, если это выглядит слишком много за один раз; вы получите это, когда мы перейдем к этой статье.

Затем давайте посмотрим на файл конфигурации broadcasting по умолчанию в config/broadcasting.php.

1
<?php
2
3
return [
4
5
    /*

6
    |--------------------------------------------------------------------------

7
    | Default Broadcaster

8
    |--------------------------------------------------------------------------

9
    |

10
    | This option controls the default broadcaster that will be used by the

11
    | framework when an event needs to be broadcast. You may set this to

12
    | any of the connections defined in the "connections" array below.

13
    |

14
    | Supported: "pusher", "redis", "log", "null"

15
    |

16
    */
17
18
    'default' => env('BROADCAST_DRIVER', 'log'),
19
20
    /*

21
    |--------------------------------------------------------------------------

22
    | Broadcast Connections

23
    |--------------------------------------------------------------------------

24
    |

25
    | Here you may define all of the broadcast connections that will be used

26
    | to broadcast events to other systems or over websockets. Samples of

27
    | each available type of connection are provided inside this array.

28
    |

29
    */
30
31
    'connections' => [
32
33
        'pusher' => [
34
            'driver' => 'pusher',
35
            'key' => env('PUSHER_APP_KEY'),
36
            'secret' => env('PUSHER_APP_SECRET'),
37
            'app_id' => env('PUSHER_APP_ID'),
38
        ],
39
40
        'redis' => [
41
            'driver' => 'redis',
42
            'connection' => 'default',
43
        ],
44
45
        'log' => [
46
            'driver' => 'log',
47
        ],
48
49
        'null' => [
50
            'driver' => 'null',
51
        ],
52
53
    ],
54
55
];

По умолчанию Laravel поддерживает несколько адаптеров в своем ядре.

В этой статье мы собираемся использовать адаптер Pusher. Для целей отладки вы также можете использовать адаптер log. Конечно, если вы используете адаптер log, клиент не получит никаких уведомлений о событиях, и он будет зарегистрирован только в файле laravel.log.

Из следующего раздела дальше мы сразу же погрузимся в фактическую реализацию вышеупомянутого варианта использования.

Настройка предварительных условий

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

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

Основная функция проверки подлинности

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

Pusher SDK - установка и настройка

Поскольку мы собираемся использовать сторонний сервис Pusher в качестве нашего сервера веб-сокетов, вам необходимо создать учетную запись и убедиться, что у вас есть необходимые учетные данные API. Если у вас возникли проблемы с его созданием, не стесняйтесь спрашивать меня в разделе комментариев.

Затем нам нужно установить Pusher PHP SDK, чтобы наше приложение Laravel могло отправлять уведомления на сервер веб-сокетов Pusher.

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

1
$composer require pusher/pusher-php-server "~3.0"

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

1
<?php
2
3
return [
4
5
    /*

6
    |--------------------------------------------------------------------------

7
    | Default Broadcaster

8
    |--------------------------------------------------------------------------

9
    |

10
    | This option controls the default broadcaster that will be used by the

11
    | framework when an event needs to be broadcast. You may set this to

12
    | any of the connections defined in the "connections" array below.

13
    |

14
    | Supported: "pusher", "redis", "log", "null"

15
    |

16
    */
17
18
    'default' => env('BROADCAST_DRIVER', 'pusher'),
19
20
    /*

21
    |--------------------------------------------------------------------------

22
    | Broadcast Connections

23
    |--------------------------------------------------------------------------

24
    |

25
    | Here you may define all of the broadcast connections that will be used

26
    | to broadcast events to other systems or over websockets. Samples of

27
    | each available type of connection are provided inside this array.

28
    |

29
    */
30
31
    'connections' => [
32
33
        'pusher' => [
34
            'driver' => 'pusher',
35
            'key' => env('PUSHER_APP_KEY'),
36
            'secret' => env('PUSHER_APP_SECRET'),
37
            'app_id' => env('PUSHER_APP_ID'),
38
            'options' => [
39
                        'cluster' => 'ap2',
40
                        'encrypted' => true
41
            ],
42
        ],
43
44
        'redis' => [
45
            'driver' => 'redis',
46
            'connection' => 'default',
47
        ],
48
49
        'log' => [
50
            'driver' => 'log',
51
        ],
52
53
        'null' => [
54
            'driver' => 'null',
55
        ],
56
57
    ],
58
59
];

Как вы можете видеть, мы изменили драйвер передачи по умолчанию на Pusher. Мы также добавили параметры конфигурации cluster и encrypted , которые вы должны были получить из учетной записи Pusher, в первую очередь.

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

1
BROADCAST_DRIVER=pusher
2
3
PUSHER_APP_ID={YOUR_APP_ID}
4
PUSHER_APP_KEY={YOUR_APP_KEY}
5
PUSHER_APP_SECRET={YOUR_APP_SECRET}

Затем мне пришлось внести несколько изменений в пару основных файлов Laravel, чтобы сделать его совместимым с последним Pusher SDK. Конечно, я не рекомендую вносить какие-либо изменения в фреймворк, но я просто остановлюсь на том, что нужно сделать.

Откройте файл vendor vendor/laravel/framework/src/Illuminate/PusherBroadcaster.php. Просто замените фрагмент use Pusher; на use Pusher\Pusher;.

Затем давайте откроем файл vendor/laravel/framework/src/Illuminate/BroadcastManager.php и сделаем аналогичное изменение в следующем фрагменте.

1
return new PusherBroadcaster(
2
  new \Pusher\Pusher($config['key'], $config['secret'],
3
  $config['app_id'], Arr::get($config, 'options', []))
4
);

Наконец, давайте включим службу broadcast в config/app.php, удалив комментарий в следующей строке.

1
App\Providers\BroadcastServiceProvider::class,

Итак, мы установили серверные библиотеки. В следующем разделе мы рассмотрим клиентские библиотеки, которые также должны быть установлены.

Библиотеки Pusher и Laravel Echo - Установка и настройка

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

К счастью, нам не нужно реализовывать какие-либо сложные вещи JavaScript для этого, поскольку Laravel уже предоставляет полезную клиентскую библиотеку Laravel Echo, которая помогает нам иметь дело с сокетами на стороне клиента. Кроме того, он поддерживает сервис Pusher, который мы собираемся использовать в этой статье.

Вы можете установить Laravel Echo, используя менеджер пакетов NPM. Конечно, вам нужно установить node и npm в первую очередь, если у вас их нет. Остальное довольно просто, как будет показано в следующем фрагменте.

1
$npm install laravel-echo

Нам интересен файл node_modules/laravel-echo/dist/echo.js, который вы должны скопировать в public/echo.js.

Да, я понимаю, это наверно перебор, получить всего один JavaScript файл. Если вы не хотите проходить это упражнение, вы можете загрузить файл echo.js из моего GitHub.

И с этим мы закончили настройку наших клиентских библиотек.

Настройка исходного файла

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

В этом разделе мы создадим файлы, необходимые для реализации используемого use case.

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

1
$php artisan make:model Message --migration

Нам также необходимо добавить несколько полей, например, to, from и message  в нашу таблицу сообщений. Итак, давайте изменим файл миграции перед запуском команды migrate.

1
<?php
2
3
use Illuminate\Support\Facades\Schema;
4
use Illuminate\Database\Schema\Blueprint;
5
use Illuminate\Database\Migrations\Migration;
6
7
class CreateMessagesTable extends Migration
8
{
9
    /**

10
     * Run the migrations.

11
     *

12
     * @return void

13
     */
14
    public function up()
15
    {
16
        Schema::create('messages', function (Blueprint $table) {
17
            $table->increments('id');
18
            $table->integer('from', FALSE, TRUE);
19
            $table->integer('to', FALSE, TRUE);
20
            $table->text('message');
21
            $table->timestamps();
22
        });
23
    }
24
25
    /**

26
     * Reverse the migrations.

27
     *

28
     * @return void

29
     */
30
    public function down()
31
    {
32
        Schema::dropIfExists('messages');
33
    }
34
}

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

1
$php artisan migrate

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

Если событие является обычным событием, Laravel вызывает связанные классы слушателей. С другой стороны, если событие имеет тип вещания, Laravel отправляет это событие на сервер веб-сокета, который настроен в файле config/broadcasting.php.

Когда мы используем сервис Pusher в нашем примере, Laravel отправит события на сервер Pusher.

Давайте используем следующую команду artisan для создания настраиваемого класса событий - NewMessageNotification.

1
$php artisan make:event NewMessageNotification

Это должно создать класс app/Events/NewMessageNotification.php. Давайте заменим содержимое этого файла следующим.

1
<?php
2
3
namespace App\Events;
4
5
use Illuminate\Broadcasting\Channel;
6
use Illuminate\Queue\SerializesModels;
7
use Illuminate\Broadcasting\PrivateChannel;
8
use Illuminate\Broadcasting\PresenceChannel;
9
use Illuminate\Broadcasting\InteractsWithSockets;
10
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
11
use App\Message;
12
13
class NewMessageNotification implements ShouldBroadcastNow
14
{
15
    use SerializesModels;
16
17
    public $message;
18
19
    /**

20
     * Create a new event instance.

21
     *

22
     * @return void

23
     */
24
    public function __construct(Message $message)
25
    {
26
        $this->message = $message;
27
    }
28
29
    /**

30
     * Get the channels the event should broadcast on.

31
     *

32
     * @return Channel|array

33
     */
34
    public function broadcastOn()
35
    {
36
        return new PrivateChannel('user.'.$this->message->to);
37
    }
38
}

Важно отметить, что класс NewMessageNotification реализует интерфейс ShouldBroadcastNow. Таким образом, когда мы поднимаем событие, Laravel знает, что это событие должно быть транслировано.

Фактически, вы также можете реализовать интерфейс ShouldBroadcast, а Laravel добавляет событие в очередь событий. Оно будет обработано работником очереди событий, когда у него появится такая возможность. В нашем случае мы хотим передать его прямо сейчас, поэтому мы использовали интерфейс ShouldBroadcastNow.

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

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

Значение $this->message->to относится к идентификатору пользователя, которому будет транслироваться событие. Таким образом имя канала подобно user.{USER_ID}.

В случае частных каналов клиент должен пройти аутентификацию до установления соединения с сервером веб-сокетов. Это гарантирует, что события, которые транслируются на частных каналах, отправляются только для аутентифицированных клиентов. В нашем случае это означает, что только зарегистрированные пользователи смогут подписаться на наш канал user.{USER_ID}.

Если вы используете клиентскую библиотеку Laravel Echo для подписки на канал, вам повезло! Она автоматически заботится о части аутентификации, и вам просто нужно определить маршруты каналов.

Давайте продолжим и добавим маршрут для нашего частного канала в файле routes/channels.php.

1
<?php
2
3
/*

4
|--------------------------------------------------------------------------

5
| Broadcast Channels

6
|--------------------------------------------------------------------------

7
|

8
| Here you may register all of the event broadcasting channels that your

9
| application supports. The given channel authorization callbacks are

10
| used to check if an authenticated user can listen to the channel.

11
|

12
*/
13
14
Broadcast::channel('App.User.{id}', function ($user, $id) {
15
    return (int) $user->id === (int) $id;
16
});
17
18
Broadcast::channel('user.{toUserId}', function ($user, $toUserId) {
19
    return $user->id == $toUserId;
20
});

Как вы можете видеть, мы определили маршрут user.{toUserId} для нашего приватного канала.

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

Когда клиент пытается подписаться на приватный канал user.{USER_ID}, библиотека Laravel Echo выполняет необходимую аутентификацию в фоновом режиме с помощью объекта XMLHttpRequest или более широко известного как XHR.

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

Настройка Front-End

В этом разделе мы создадим файлы, необходимые для тестирования нашего use-case.

Давайте продолжим и создадим файл контроллера в app/Http/Controllers/MessageController.php со следующим содержимым.

1
<?php
2
namespace App\Http\Controllers;
3
4
use App\Http\Controllers\Controller;
5
use App\Message;
6
use App\Events\NewMessageNotification;
7
use Illuminate\Support\Facades\Auth;
8
9
class MessageController extends Controller
10
{
11
    public function __construct() {
12
        $this->middleware('auth');
13
    }
14
15
    public function index()
16
    {
17
        $user_id = Auth::user()->id;
18
        $data = array('user_id' => $user_id);
19
20
        return view('broadcast', $data);
21
    }
22
23
    public function send()
24
    {
25
        // ...

26
        
27
        // message is being sent

28
        $message = new Message;
29
        $message->setAttribute('from', 1);
30
        $message->setAttribute('to', 2);
31
        $message->setAttribute('message', 'Demo message from user 1 to user 2');
32
        $message->save();
33
        
34
        // want to broadcast NewMessageNotification event

35
        event(new NewMessageNotification($message));
36
        
37
        // ...

38
    }
39
}

В методе index мы используем представление broadcast, поэтому давайте создадим файл представлений resources/views/broadcast.blade.php.

1
<!DOCTYPE html>
2
<html lang="{{ app()->getLocale() }}">
3
<head>
4
    <meta charset="utf-8">
5
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
    <meta name="viewport" content="width=device-width, initial-scale=1">
7
8
    <!-- CSRF Token -->
9
    <meta name="csrf-token" content="{{ csrf_token() }}">
10
11
    <title>Test</title>
12
13
    <!-- Styles -->
14
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
15
</head>
16
<body>
17
    <div id="app">
18
        <nav class="navbar navbar-default navbar-static-top">
19
            <div class="container">
20
                <div class="navbar-header">
21
22
                    <!-- Collapsed Hamburger -->
23
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
24
                        <span class="sr-only">Toggle Navigation</span>
25
                        <span class="icon-bar"></span>
26
                        <span class="icon-bar"></span>
27
                        <span class="icon-bar"></span>
28
                    </button>
29
30
                    <!-- Branding Image -->
31
                    <a class="navbar-brand123" href="{{ url('/') }}">
32
                        Test
33
                    </a>
34
                </div>
35
36
                <div class="collapse navbar-collapse" id="app-navbar-collapse">
37
                    <!-- Left Side Of Navbar -->
38
                    <ul class="nav navbar-nav">
39
                        &nbsp;
40
                    </ul>
41
42
                    <!-- Right Side Of Navbar -->
43
                    <ul class="nav navbar-nav navbar-right">
44
                        <!-- Authentication Links -->
45
                        @if (Auth::guest())
46
                            <li><a href="{{ route('login') }}">Login</a></li>
47
                            <li><a href="{{ route('register') }}">Register</a></li>
48
                        @else
49
                            <li class="dropdown">
50
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
51
                                    {{ Auth::user()->name }} <span class="caret"></span>
52
                                </a>
53
54
                                <ul class="dropdown-menu" role="menu">
55
                                    <li>
56
                                        <a href="{{ route('logout') }}"
57
                                            onclick="event.preventDefault();

58
                                                     document.getElementById('logout-form').submit();">
59
                                            Logout
60
                                        </a>
61
62
                                        <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
63
                                            {{ csrf_field() }}
64
                                        </form>
65
                                    </li>
66
                                </ul>
67
                            </li>
68
                        @endif
69
                    </ul>
70
                </div>
71
            </div>
72
        </nav>
73
74
        <div class="content">
75
                <div class="m-b-md">
76
                    New notification will be alerted realtime!
77
                </div>
78
        </div>
79
    </div>
80
81
    <!-- receive notifications -->
82
    <script src="{{ asset('js/echo.js') }}"></script>
83
84
    <script src="https://js.pusher.com/4.1/pusher.min.js"></script>
85
        
86
        <script>
87
          Pusher.logToConsole = true;
88
        
89
          window.Echo = new Echo({
90
            broadcaster: 'pusher',
91
            key: 'c91c1b7e8c6ece46053b',
92
            cluster: 'ap2',
93
            encrypted: true,
94
            logToConsole: true
95
          });
96
        
97
          Echo.private('user.{{ $user_id }}')
98
          .listen('NewMessageNotification', (e) => {
99
              alert(e.message.message);
100
          });
101
        </script>
102
    <!-- receive notifications -->
103
</body>
104
</html>

И, конечно же, нам нужно добавить маршруты и в файл routes/web.php.

1
Route::get('message/index', 'MessageController@index');
2
Route::get('message/send', 'MessageController@send');

В методе конструктора класса контроллера вы можете видеть, что мы использовали middleware auth, чтобы убедиться, что методы контроллера доступны только зарегистрированным пользователям.

Далее, есть метод index, который отображает вьюшку broadcast. Давайте возьмем самый важный код в файле отображения.

1
<!-- receive notifications -->
2
<script src="{{ asset('js/echo.js') }}"></script>
3
4
<script src="https://js.pusher.com/4.1/pusher.min.js"></script>
5
    
6
<script>
7
    Pusher.logToConsole = true;
8
9
    window.Echo = new Echo({
10
        broadcaster: 'pusher',
11
        key: 'c91c1b7e8c6ece46053b',
12
        cluster: 'ap2',
13
        encrypted: true,
14
        logToConsole: true
15
    });
16
17
    Echo.private('user.{{ $user_id }}')
18
    .listen('NewMessageNotification', (e) => {
19
        alert(e.message.message);
20
    });
21
</script>
22
<!-- receive notifications -->

Во-первых, мы загружаем необходимые клиентские библиотеки, Laravel Echo и Pusher, что позволяет нам открыть соединение веб-сокетов с сервером веб-сокетов Pusher.

Затем мы создаем экземпляр Echo, предоставляя Pusher в качестве нашего адаптера и другую необходимую информацию, связанную с Pusher.

Двигаясь дальше, мы используем метод private Echo для подписки на пользователя на приватный канал user.{USER_ID}. Как мы обсуждали ранее, клиент должен пройти аутентификацию перед подпиской на приватный канал. Таким образом, объект Echo выполняет необходимую аутентификацию, отправляя XHR в фоновом режиме с необходимыми параметрами. Наконец, Laravel пытается найти маршрут user.{USER_ID}, и он должен соответствовать маршруту, который мы определили в файле routes/channels.php.

Если все пройдет хорошо, у вас должно быть соединение с веб-сокетом с сервером веб-сокетов Pusher, и он слушает события на канале user.{USER_ID}! С этого момента мы получим все входящие события на этом канале.

В нашем случае мы хотим прослушать событие NewMessageNotification, и поэтому мы использовали метод listen объекта Echo. Чтобы все было просто, мы просто выводит сообщение с помощью alert.

Таким образом, это была настройка для приема событий с сервера веб-сокетов. Затем мы рассмотрим метод send в файле контроллера, который вызывает событие трансляции.

Давайте быстро введем код метода send.

1
public function send()
2
{
3
    // ...

4
    
5
    // message is being sent

6
    $message = new Message;
7
    $message->setAttribute('from', 1);
8
    $message->setAttribute('to', 2);
9
    $message->setAttribute('message', 'Demo message from user 1 to user 2');
10
    $message->save();
11
    
12
    // want to broadcast NewMessageNotification event

13
    event(new NewMessageNotification($message));
14
    
15
    // ...

16
}

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

Затем мы использовали функцию помощник event, чтобы создать событие NewMessageNotification. Поскольку событие NewMessageNotification имеет тип ShouldBroadcastNow, Laravel загружает конфигурацию broadcast по умолчанию из файла config/broadcasting.php. Наконец, он транслирует событие NewMessageNotification на настроенный сервер веб-сокетов на канал user.{USER_ID}.

В нашем случае событие будет транслироваться на сервер веб-сокетов Pusher на канал user.{USER_ID}. Если идентификатор пользователя-получателя равен 1, событие будет транслироваться по каналу user.1.

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

Давайте продолжим и рассмотрим, как вы должны тестировать этот use-case, который мы создали.

Откройте в вашем браузере адрес http://your-laravel-site-domain/message/index. Если вы еще не вошли в систему, вы будете перенаправлены на экран входа в систему. После того, как вы вошли в систему, вы должны увидеть представление, которое мы определили ранее, пока ничего интересного.

На самом деле, Laravel уже проделал довольно много работы на заднем плане для вас. Поскольку мы включили параметр Pusher.logToConsole, предоставленный клиентской библиотекой Pusher, то для целей отладки он регистрирует все события в консоли браузера. Посмотрим, что регистрируется на консоли при доступе к странице http://your-laravel-site-domain/message/index.

1
Pusher : State changed : initialized -> connecting
2
3
Pusher : Connecting : {"transport":"ws","url":"wss://ws-ap2.pusher.com:443/app/c91c1b7e8c6ece46053b?protocol=7&client=js&version=4.1.0&flash=false"}
4
5
Pusher : Connecting : {"transport":"xhr_streaming","url":"https://sockjs-ap2.pusher.com:443/pusher/app/c91c1b7e8c6ece46053b?protocol=7&client=js&version=4.1.0"}
6
7
Pusher : State changed : connecting -> connected with new socket ID 1386.68660
8
9
Pusher : Event sent : {"event":"pusher:subscribe","data":{"auth":"c91c1b7e8c6ece46053b:cd8b924580e2cbbd2977fd4ef0d41f1846eb358e9b7c327d89ff6bdc2de9082d","channel":"private-user.2"}}
10
11
Pusher : Event recd : {"event":"pusher_internal:subscription_succeeded","data":{},"channel":"private-user.2"}
12
13
Pusher : No callbacks on private-user.2 for pusher:subscription_succeeded

Было открыто соединение с веб-сокетом с сервером веб-сокетов Pusher и была подписка на прослушивание событий на приватном канале. Конечно, у вас может быть другое имя канала в вашем случае на основе идентификатора пользователя, с которым вы вошли в систему. Теперь давайте оставим эту страницу открытой, и перейдем, чтобы протестировать метод send.

Затем давайте откроем URL-адрес http://your-laravel-site-domain/message/send на другой вкладке или в другом браузере. Если вы собираетесь использовать другой браузер, вам нужно войти в систему, чтобы иметь доступ к этой странице.

Как только вы откроете страницу http://your-laravel-site-domain/message/send, вы сможете увидеть предупреждающее сообщение на другой вкладке по адресу http://your-laravel-site-domain/message/index.

Перейдем к консоли, чтобы увидеть, что только что произошло.

1
Pusher : Event recd : {"event":"App\\Events\\NewMessageNotification","data":{"message":{"id":57,"from":1,"to":2,"message":"Demo message from user 1 to user 2","created_at":"2018-01-13 07:10:10","updated_at":"2018-01-13 07:10:10"}},"channel":"private-user.2"}

Как вы можете видеть, он сообщает вам, что вы только что получили событие App\Events\NewMessageNotification от сервера веб-сокетов Pusher на канале private-user.2.

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

Pusher DashboardPusher DashboardPusher Dashboard

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

Заключение

Сегодня мы рассмотрели одну из наименее обсуждаемых особенностей Laravel- broadcasting. Она позволяет отправлять уведомления в режиме реального времени с помощью веб-сокетов. На протяжении всей этой статьи мы построили реальный пример, демонстрирующий вышеупомянутую концепцию.

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

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.