This post assumes you have the initial set up of pusher & echo in Laravel
I wanted a way to keep track of users in a chat room where two things were important
- Signed in user list
- User count (including non signed in users)
Public channels made it work but not very smoothly.
Here's how it was handled
1. Signed in viewers
I had
- A DB table(
chat_users
) withuser_id
andchat_id
to keep track of active users - An onMounted hook that updated DB when a user joined
- An unMounted hook that updated DB when a user left
- A Cronjob that queried
chat_users
and pushed a list to each channel on a websocket
This was suboptimal because
- Hooks were unreliable
- State management was complex
- Viewer list was not always up to date
2. Viewer count
Use the subscription_count
hook available on public channels
The move to Presence channels
Presence channels made handling active viewers very easy because of the websocket hooks it offered. Presence channels offer
- joined hook -> triggers when user joins chat, returns joining user
- left hook -> triggers when user leaves chat, returns leaving user
- here hook -> triggers when connection is made, returns active users
Handling viewer count got more difficult because
- Presence channels are private
- Presence channels lack the
subscription_count
hook
To fix this, I made a workaround to make presence channels allow guests.
Like with everything in laravel there's an easy work around.
Here's how auth in channels work & what i found.
Broadcast provider authentication
The authentication flow for channels goes
- Middlewares passed into
Broadcast::routes()
(or default if nothing is passed in) in app/Providers/BroadcastServiceProvider - Broadcast channel route in
channels.php
Guests fail the auth in step #1.
Here's how to get around that.
1. Generate a new middleware
We need to generate a middleware to pass in to Broadcast::routes()
This middleware is only for handling guests.
it should not affect auth users
- Run
php artisan make:middleware AuthenticateGuest
and add the code below
2. Register our middleware
- Add the middleware to app/Http/Kernel.php
- Add it to BroadcastProvider.php
The order matters, regular auth needs be first or every user would be a guest.
3. Confirm your channel authentication
This will make sure everyone has access to your channel
and here is how it looks when guests join