Broadcasting
Set up Pusher, Laravel Reverb, or another WebSocket server for real-time messaging
Chatify uses Laravel Broadcasting to deliver real-time events to connected clients. You need a working WebSocket server for typing indicators, new messages, read receipts, and presence updates.
How it works
- A server-side action (sending a message, reading a conversation, etc.) dispatches a broadcast event
- The event is sent to the broadcasting driver (Pusher, Reverb, etc.)
- The frontend listens on the appropriate channel via Laravel Echo
- The UI updates in real time
Pusher
Pusher is a hosted WebSocket service. It is the easiest option to get started.
1. Install the PHP SDK
composer require pusher/pusher-php-server2. Configure .env
BROADCAST_CONNECTION=pusher
PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=mt13. Enable client events
In your Pusher dashboard, go to App Settings and enable Client Events. Chatify uses client events for typing indicators.
4. Verify
Start your Laravel app and open the messenger. Messages should appear in real time across multiple browser tabs.
Laravel Reverb
Laravel Reverb is a first-party, self-hosted WebSocket server included with Laravel.
1. Install Reverb
php artisan install:broadcastingThis installs the laravel/reverb package and publishes the config.
2. Configure .env
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=your-app-id
REVERB_APP_KEY=your-app-key
REVERB_APP_SECRET=your-app-secret
REVERB_HOST=localhost
REVERB_PORT=8080
REVERB_SCHEME=http
PUSHER_APP_KEY="${REVERB_APP_KEY}"
PUSHER_HOST="${REVERB_HOST}"
PUSHER_PORT="${REVERB_PORT}"
PUSHER_APP_USETLS=falseChatify's frontend reads the PUSHER_* env vars for its Echo connection. When using Reverb, map them to the Reverb values as shown above.
3. Start the Reverb server
php artisan reverb:startFor production, run Reverb behind a reverse proxy (Nginx/Caddy) with TLS:
REVERB_SCHEME=https
REVERB_PORT=443
PUSHER_APP_USETLS=trueOther WebSocket servers
Any WebSocket server that implements the Pusher protocol works with Chatify. For example, beyondcode/laravel-websockets:
Configuration pattern
BROADCAST_CONNECTION=pusher
PUSHER_APP_ID=local
PUSHER_APP_KEY=local
PUSHER_APP_SECRET=local
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_APP_USETLS=falseSet PUSHER_HOST and PUSHER_PORT to your WebSocket server's address, and set PUSHER_APP_USETLS=false for local development.
Broadcast channels
Chatify registers two private broadcast channels:
Conversation channel
private-chatify.conversation.{conversationId}Used for events scoped to a conversation:
MessageSentMessageUpdatedMessageDeletedConversationReadUserTypingGroupParticipantsChanged
User channel
private-chatify.user.{userId}Used for events targeted at a specific user:
ConversationInboxUpdated(alias:InboxUpdated)UserPresenceChangedUserBlockChangedGroupMembershipRevoked
Channel authorization
Chatify publishes a routes/chatify/channels.php file that defines the authorization logic:
Broadcast::channel('chatify.conversation.{conversationId}', function ($user, string $conversationId) {
return ConversationParticipant::query()
->where('conversation_id', $conversationId)
->where('user_id', $user->getKey())
->exists();
});
Broadcast::channel('chatify.user.{userId}', function ($user, int|string $userId) {
return (int) $user->getKey() === (int) $userId;
});A user can only listen to conversation channels they participate in, and user channels that match their own ID.
Broadcasting auth endpoint
Chatify includes its own broadcasting auth endpoint for the frontend:
POST /api/chatify/v1/broadcasting/authThis handles channel authorization using the same middleware as the rest of the API.
Frontend Echo connection
The bundled UI automatically configures Laravel Echo using the boot data injected into the page. The connection settings come from config/chatify.php:
'frontend' => [
'broadcast' => [
'driver' => env('CHATIFY_BROADCAST_DRIVER', env('BROADCAST_CONNECTION', 'null')),
'key' => env('PUSHER_APP_KEY'),
'cluster' => env('PUSHER_APP_CLUSTER', 'mt1'),
'wsHost' => env('PUSHER_HOST'),
'wsPort' => (int) env('PUSHER_PORT', 443),
'forceTLS' => env('PUSHER_APP_USETLS', true),
],
],If you are building a custom frontend, use these values to configure your own Echo instance.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Messages send but don't appear in real time | Broadcasting driver not configured, or WebSocket server not running |
403 on channel auth | User is not a participant, or auth middleware mismatch |
| Typing indicators don't work | Client events not enabled in Pusher dashboard |
| Connection refused | Wrong PUSHER_HOST / PUSHER_PORT, or WebSocket server is down |
| Works locally but not in production | Missing TLS. Set PUSHER_APP_USETLS=true and PUSHER_PORT=443 |