Laravel: події, слухачі й бродкастинг
20 питань · ~20 хв · Версія v3.0
Увійдіть, щоб продовжити
Виявлення й реєстрація слухачів, слухачі в черзі з дебаунсом і унікальністю, відкладені події, події моделей, підміни в тестах, бродкастинг і авторизація каналів - питання всіх рівнів, від junior до lead.
- За спробу
- 20
- У пулі
- 48
- Проходжень
- 0
- Середній бал
- -
- Пройшли на 70%+
- -
Питання для підготовки
19 питань- CQRS (Command Query Responsibility Segregation) розділяє запис (Commands, що змінюють стан) і читання (Queries). Read-модель можна оптимізувати окремо (денормалізовані проєкції, окрема БД).
- Event Sourcing зберігає не поточний стан, а послідовність подій; поточний стан відновлюється їх відтворенням. Дає повний аудит і «подорож у часі».
// концептуально
$aggregate->retrieve($uuid)
->placeOrder($data) // emit OrderPlaced
->persist(); // зберегти подію
У Laravel зазвичай через пакет spatie/laravel-event-sourcing (aggregates, projectors, reactors). Застосовувати варто там, де критичні аудит і складна доменна логіка - це додає суттєву складність, тож не для типового CRUD.
Події дають слабке зв'язування: одна частина застосунку «оголошує», що щось сталося, інші - реагують, нічого не знаючи одна про одну.
event(new OrderShipped($order)); // диспатч
// слухач
class SendShipmentNotification
{
public function handle(OrderShipped $event): void
{
// ...
}
}
- Слухача, що реалізує
ShouldQueue, обробляють асинхронно в черзі. - У сучасному Laravel слухачі автоматично виявляються за type-hint у методі
handle- ручна реєстрація не обов'язкова.
Приклад: подія UserRegistered → слухачі «надіслати лист», «нарахувати бонус», «оновити статистику».
Observer групує слухачів подій моделі (creating, created, updating, saved, deleting тощо) в один клас - замість роздування boot() моделі.
class PostObserver
{
public function creating(Post $post): void
{
$post->slug = Str::slug($post->title);
}
public function deleted(Post $post): void
{
$post->image()->delete();
}
}
Реєстрація - атрибутом #[ObservedBy(PostObserver::class)] на моделі або в Service Provider. Зручно для генерації slug, очищення пов'язаних ресурсів, аудиту.
Broadcasting транслює серверні події на клієнт через WebSockets - для оновлень у реальному часі (чати, нотифікації).
class MessageSent implements ShouldBroadcast
{
public function broadcastOn(): array
{
return [new PrivateChannel('chat.'.$this->roomId)];
}
}
На клієнті Laravel Echo підписується на канал:
Echo.private(`chat.${roomId}`)
.listen('MessageSent', (e) => console.log(e.message));
Сервер WebSockets - Laravel Reverb (офіційний), Pusher або Soketi. Канали бувають public, private (з авторизацією) і presence (зі списком учасників).
WebSocket - постійне двостороннє з'єднання поверх одного TCP, що дає реальний час без поллінгу.
У Laravel сервер WebSockets - Reverb (офіційний), Soketi або Pusher; події транслюються через Broadcasting, клієнт слухає через Echo.
Масштабування: коли інстансів WebSocket-сервера кілька, клієнти на різних інстансах не «бачать» одне одного. Рішення - Redis Pub/Sub як спільна шина: інстанс публікує повідомлення в Redis, усі інстанси отримують і розсилають своїм підключеним клієнтам.
client A ─ inst 1 ┐
├─ Redis Pub/Sub ─┤
client B ─ inst 2 ┘
Окрема увага: авторизація private/presence-каналів, ліміти відкритих з'єднань, sticky sessions на балансувальнику.
Прочитати - ще не значить знати
20 питань, по одному на екран, ~20 хв. Після завершення - розбір кожної помилки з посиланням на питання.