# Laravel WebSockets Setup Guide

This guide will help you set up Laravel WebSockets as a free alternative to Pusher for real-time broadcasting in your Laravel application.

## Prerequisites

- Laravel 9.x
- PHP 8.0+
- Composer
- Node.js (for frontend assets)

## Installation Steps

### 1. Package Installation

The `beyondcode/laravel-websockets` package is already installed in your project. If you need to install it manually:

```bash
composer require beyondcode/laravel-websockets
```

### 2. Publish Configuration and Migrations

```bash
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"
php artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"
```

### 3. Run Migrations

```bash
php artisan migrate
```

### 4. Environment Configuration

Add the following to your `.env` file:

```env
# Broadcasting Configuration
BROADCAST_DRIVER=pusher

# Pusher Configuration (for Laravel WebSockets compatibility)
PUSHER_APP_ID=12345
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=mt1

# Laravel WebSockets Configuration
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
LARAVEL_WEBSOCKETS_PORT=6001

# Queue Configuration (recommended for broadcasting)
QUEUE_CONNECTION=database
```

### 5. Update Broadcasting Configuration

The `config/broadcasting.php` file has been updated to use local WebSocket server settings.

### 6. Update Frontend Configuration

Update your `resources/js/bootstrap.js` file to use the local WebSocket server:

```javascript
window.Echo = new Echo({
    authEndpoint: base_path + '/broadcasting/auth',
    broadcaster: 'pusher',
    key: APP.PUSHER_APP_KEY,
    cluster: APP.PUSHER_APP_CLUSTER,
    // Use local WebSocket server instead of Pusher
    host: window.location.hostname,
    port: 6001,
    forceTLS: false, // Set to false for local development
    encrypted: false, // Set to false for local development
    disableStats: true,
    enabledTransports: ['ws', 'wss']
});
```

## Starting the WebSocket Server

### Development

Start the WebSocket server:

```bash
php artisan websockets:serve
```

### Production

For production, you should use a process manager like Supervisor. Create a configuration file:

```ini
[program:laravel-websockets]
process_name=%(program_name)s
command=php /path/to/your/project/artisan websockets:serve
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/path/to/your/project/storage/logs/websockets.log
```

## Testing the Setup

### 1. Test Page

Visit `/websocket/test` to access the WebSocket test page.

### 2. API Endpoints

- `GET /websocket/status` - Check WebSocket configuration
- `POST /websocket/test` - Send a test message
- `GET /laravel-websockets` - WebSocket dashboard

### 3. Manual Testing

You can test WebSocket functionality by:

1. Opening the test page in multiple browser tabs
2. Sending messages from one tab
3. Observing real-time updates in other tabs

## Creating Broadcast Events

### Example Event

```php
<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class MyEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function broadcastOn()
    {
        return new Channel('my-channel');
    }

    public function broadcastAs()
    {
        return 'my-event';
    }
}
```

### Dispatching Events

```php
event(new MyEvent(['message' => 'Hello World!']));
```

## Frontend Event Listening

### Public Channels

```javascript
window.Echo.channel('my-channel')
    .listen('MyEvent', (e) => {
        console.log('Received:', e);
    });
```

### Private Channels

```javascript
window.Echo.private('private-channel')
    .listen('PrivateEvent', (e) => {
        console.log('Private event:', e);
    });
```

### Presence Channels

```javascript
window.Echo.join('presence-channel')
    .here((users) => {
        console.log('Users currently in the channel:', users);
    })
    .joining((user) => {
        console.log('User joined:', user);
    })
    .leaving((user) => {
        console.log('User left:', user);
    });
```

## Troubleshooting

### Common Issues

1. **WebSocket connection failed**
   - Ensure the WebSocket server is running
   - Check firewall settings
   - Verify port 6001 is not blocked

2. **Events not broadcasting**
   - Check `BROADCAST_DRIVER` is set to `pusher`
   - Verify event implements `ShouldBroadcast`
   - Check queue configuration

3. **Frontend not receiving events**
   - Ensure Echo is properly configured
   - Check browser console for errors
   - Verify channel names match

### Debug Commands

```bash
# Check WebSocket server status
php artisan websockets:serve --debug

# Clear configuration cache
php artisan config:clear

# Restart queue workers
php artisan queue:restart
```

## Security Considerations

1. **Authentication**: Use private channels for sensitive data
2. **Authorization**: Implement proper channel authorization
3. **Rate Limiting**: Consider implementing rate limiting for WebSocket connections
4. **SSL**: Use HTTPS/WSS in production

## Performance Optimization

1. **Queue Workers**: Use queue workers for event broadcasting
2. **Redis**: Consider using Redis for better performance
3. **Monitoring**: Monitor WebSocket server performance
4. **Scaling**: Use multiple WebSocket servers for high-traffic applications

## Additional Resources

- [Laravel WebSockets Documentation](https://beyondco.de/docs/laravel-websockets/)
- [Laravel Broadcasting Documentation](https://laravel.com/docs/broadcasting)
- [Pusher Protocol Documentation](https://pusher.com/docs/channels/library_auth_reference/pusher-websockets-protocol) 