# Realtime Messaging Skinbase Nova messaging now uses Laravel Reverb, Laravel Broadcasting, Laravel Echo, Redis-backed queues, and Laravel Horizon for queue visibility. ## v2 capabilities - Presence is exposed through a global `presence-messaging` channel for inbox-level online state. - Conversation presence still uses the per-thread presence channel so the header can show who is actively viewing the room. - Typing indicators remain ephemeral and Redis-backed. - Read markers are stored on conversation participants and expanded into `message_reads` for durable receipts. - The conversation list response now includes `summary.unread_total` for global badge consumers. - Reconnect recovery uses `GET /api/messages/{conversation_id}/delta?after_message_id=...`. - Delta recovery also returns the latest conversation summary and aggregate unread total so the inbox sidebar can heal after a missed `conversation.updated` broadcast. - Presence heartbeats use `POST /api/messages/presence/heartbeat` and are intended only to support offline fallback notification logic plus server-side presence awareness. - Message sends are idempotent per sender and conversation when the client retries with the same `client_temp_id`. - The database also enforces sender-scoped `client_temp_id` uniqueness so retry races cannot persist duplicate rows. ## Local setup 1. Set the Reverb, Redis, messaging, and Horizon values in `.env`. 2. Run `php artisan migrate`. 3. Run `npm install` if dependencies are not installed. 4. Start the websocket server with `php artisan reverb:start --host=0.0.0.0 --port=8080`. 5. Start queue workers with `php artisan queue:work redis --queue=broadcasts,notifications,default --tries=1`. 6. Start the frontend with `npm run dev` or build assets with `npm run build`. ## Horizon - Horizon is installed for production queue monitoring and uses dedicated supervisors for `broadcasts` and `notifications` alongside the default queue. - The scheduler now runs `php artisan horizon:snapshot` every five minutes so the dashboard records queue metrics. - On Windows development machines, Horizon itself cannot run because PHP lacks `ext-pcntl` and `ext-posix`; that limitation does not affect Linux production deployments. - Use `php artisan horizon` on Linux-based environments and keep the dashboard behind the `viewHorizon` gate. ## Production notes - Use `BROADCAST_CONNECTION=reverb` and `QUEUE_CONNECTION=redis`. - Keep `MESSAGING_REALTIME=true` only when Reverb is configured and reachable from the browser. - Terminate TLS in Nginx and proxy websocket traffic to the Reverb process. - Run `php artisan reverb:start` and `php artisan horizon` under Supervisor or systemd. - The chat UI falls back to HTTP polling only when realtime is disabled in config. - Database notification fallback now only runs for recipients who are not marked online in messaging presence. ## Reconnect model - The conversation view loads once via HTTP. - Live message, read, typing, and conversation summary updates arrive over websocket channels. - When the socket reconnects, the client requests deltas from the explicit `delta` endpoint and merges them idempotently by message id, UUID, and client temp id. - HTTP send retries also reuse the original stored message when `client_temp_id` matches, preventing duplicate broadcasts during reconnect races.