Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке канали присутності і клієнтські події (whisper) і як зробити «хто онлайн» та «набирає повідомлення»?

Канал присутності (presence channel) - приватний канал, який додатково знає, хто саме в ньому зараз. Ідеальний для чатів, спільного редагування, списку «зараз переглядають».

Авторизація відрізняється від звичайного приватного каналу: колбек повертає масив даних про користувача, а не true:

// routes/channels.php
Broadcast::channel('chat.{roomId}', function (User $user, int $roomId) {
    if ($user->canJoinRoom($roomId)) {
        return ['id' => $user->id, 'name' => $user->name];
    }
});

Ці дані побачать усі учасники каналу - не повертайте туди email, телефони чи інші приватні поля.

Приєднання на фронтенді:

Echo.join(`chat.${roomId}`)
    .here((users) => { online.value = users; })          // хто вже в каналі
    .joining((user) => { online.value.push(user); })      // хтось прийшов
    .leaving((user) => { remove(user); })                 // хтось пішов
    .listen('NewMessage', (e) => { messages.value.push(e.message); });

Клієнтські події (whisper) - повідомлення від одного клієнта іншим без звернення до Laravel:

// відправник
Echo.private(`chat.${roomId}`).whisper('typing', { name: user.name });

// отримувачі
Echo.private(`chat.${roomId}`).listenForWhisper('typing', (e) => {
    showTyping(e.name);
});

Застосунок не бачить цих повідомлень, тому:

  • whisper - лише для ефемерних, неважливих сигналів: «набирає», курсор співрозмовника, «переглядає зараз»;
  • нічого, що має зберігатися чи перевірятися (повідомлення чату, зміни даних), через whisper не йде - тільки через HTTP-запит до застосунку, який валідує, зберігає й транслює подію;
  • whisper працює лише в приватних каналах і каналах присутності; у Pusher клієнтські події треба окремо увімкнути в налаштуваннях застосунку.

toOthers() - щоб відправник не отримав власну подію повторно:

broadcast(new NewMessage($message))->toOthers();

Echo автоматично додає заголовок X-Socket-ID до запитів, і Laravel виключає це з'єднання з отримувачів.

Нюанси: користувач з двома вкладками - два з'єднання, але в списку присутності він один (учасники об'єднуються за id). Події leaving приходять із затримкою при обриві мережі - сервер виявляє мертве з'єднання не миттєво.

Докладніше в документації: Broadcasting: канали присутності

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання