Laravel Integration Guide
Vask is fully compatible with Laravel Broadcasting and Laravel Echo.
Installation
We recommend following Laravel's broadcasting documentation to get setup.
Then you only need to set the environment variables to your vask app details.
Configuration
Environment Variables
Add your Vask credentials to your .env file:
BROADCAST_CONNECTION=pusher
PUSHER_APP_ID=your_app_id
PUSHER_APP_KEY=your_app_id
PUSHER_APP_SECRET=your_app_secret
PUSHER_HOST=wss.vask.dev
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1Broadcasting Events
Creating a Broadcast Event
Create an event that implements ShouldBroadcast:
<?php
namespace App\Events;
use App\Models\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(
public Message $message,
public string $userName
) {}
public function broadcastOn(): Channel
{
return new Channel('chat.' . $this->message->room_id);
}
public function broadcastAs(): string
{
return 'message.sent';
}
public function broadcastWith(): array
{
return [
'id' => $this->message->id,
'content' => $this->message->content,
'user' => $this->userName,
'created_at' => $this->message->created_at->toISOString(),
];
}
}Triggering Events
Broadcast events from your controllers or anywhere in your application:
use App\Events\MessageSent;
// In a controller method
public function sendMessage(Request $request)
{
$message = Message::create([
'room_id' => $request->room_id,
'user_id' => auth()->id(),
'content' => $request->content,
]);
// Broadcast the event
broadcast(new MessageSent(
$message,
auth()->user()->name
));
return response()->json($message);
}
// Or use the event() helper
event(new MessageSent($message, $userName));
// For immediate broadcasting (bypass queue)
broadcast(new MessageSent($message, $userName))->toOthers();Client-Side Setup
Configure Laravel Echo
Initialize Echo in your bootstrap.js or app.{js,ts,tsx} file:
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
wsHost: import.meta.env.VITE_PUSHER_HOST,
wsPort: import.meta.env.VITE_PUSHER_PORT,
wssPort: import.meta.env.VITE_PUSHER_PORT,
forceTLS: true,
encrypted: true,
disableStats: true,
enabledTransports: ['ws', 'wss'],
});Listening to Events
Subscribe to channels and listen for events in your components:
// Listen to a public channel
Echo.channel('chat.1').listen('.message.sent', (event) => {
console.log('New message:', event);
// Update your UI with the new message
addMessageToChat(event);
});
// Listen to multiple events
Echo.channel('notifications')
.listen('.user.joined', (e) => {
console.log(e.userName + ' joined');
})
.listen('.user.left', (e) => {
console.log(e.userName + ' left');
});
// Leave a channel
Echo.leave('chat.1');Private Channels
Authorization Routes
Define channel authorization logic in routes/channels.php:
<?php
use App\Models\User;
use App\Models\Room;
use Illuminate\Support\Facades\Broadcast;
// Private channel authorization
Broadcast::channel('room.{roomId}', function (User $user, int $roomId) {
// Return true if user can access this room
return $user->rooms()->where('room_id', $roomId)->exists();
});
// Return data with authorization
Broadcast::channel('user.{userId}', function (User $user, int $userId) {
if ($user->id === $userId) {
return [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar_url,
];
}
return false;
});Broadcasting to Private Channels
use Illuminate\Broadcasting\PrivateChannel;
class OrderStatusUpdated implements ShouldBroadcast
{
public function broadcastOn(): Channel
{
return new PrivateChannel('user.' . $this->order->user_id);
}
}Listening to Private Channels
// Subscribe to a private channel
Echo.private('user.' + userId)
.listen('.order.updated', (event) => {
console.log('Order updated:', event.order);
})
.listen('.payment.received', (event) => {
showNotification('Payment received: $' + event.amount);
});Presence Channels
Presence channels let you track who's online in real-time.
Authorization with User Data
Broadcast::channel('chat.{roomId}', function (User $user, int $roomId) {
if ($user->canJoinRoom($roomId)) {
return [
'id' => $user->id,
'name' => $user->name,
'avatar' => $user->avatar_url,
];
}
});Using Presence Channels
use Illuminate\Broadcasting\PresenceChannel;
class UserJoinedRoom implements ShouldBroadcast
{
public function broadcastOn(): Channel
{
return new PresenceChannel('room.' . $this->roomId);
}
}Client-Side Presence
let onlineUsers = [];
Echo.join('room.' + roomId)
.here((users) => {
// Initial users in the channel
console.log('Users online:', users);
onlineUsers = users;
updateUsersList(users);
})
.joining((user) => {
// User joined the channel
console.log(user.name + ' joined');
onlineUsers.push(user);
addUserToList(user);
})
.leaving((user) => {
// User left the channel
console.log(user.name + ' left');
onlineUsers = onlineUsers.filter((u) => u.id !== user.id);
removeUserFromList(user);
})
.error((error) => {
console.error('Connection error:', error);
})
.listen('.message.sent', (event) => {
// Listen to events on presence channel
addMessageToChat(event);
});Troubleshooting
Connection Issues
Problem: "Failed to connect to Pusher".
Solution: Check your .env credentials and ensure PUSHER_HOST is set to wss.vask.dev.
Events Not Broadcasting
Problem: Events are not being received by clients.
Solutions:
- Ensure your queue worker is running:
php artisan queue:work. - Check that
BROADCAST_CONNECTION=pusherin.env. - Verify the event implements
ShouldBroadcast. - Check Laravel logs for broadcasting errors.
Private Channel Authorization Failing
Problem: 403 Forbidden when joining private channels.
Solutions:
- Verify authorization logic in
routes/channels.php. - Ensure user is authenticated before subscribing.
- Check that channel names match between backend and frontend.
- Verify CSRF token is being sent with authorization requests.
Debug Mode
Enable Pusher debug mode to see detailed logs:
window.Echo = new Echo({
// ... other config
enabledTransports: ['ws', 'wss'],
// Enable debug mode
enableLogging: true,
});
// Also enable Pusher logging
Pusher.logToConsole = true;Next Steps
Prefer raw markdown? View this page as markdown.