Канал присутності (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 приходять із затримкою при обриві мережі - сервер виявляє мертве з'єднання не миттєво.