# راهنمای راه‌اندازی WebSocket برای ردیابی لحظه‌ای موقعیت رانندگان

## نصب و پیکربندی

سیستم WebSocket برای ردیابی لحظه‌ای موقعیت رانندگان با استفاده از پکیج `beyondcode/laravel-websockets` پیاده‌سازی شده است.

### 1. پیش‌نیازها

- PHP 8.1 یا بالاتر
- Laravel 10.x
- دسترسی به پورت 6001 (پورت پیش‌فرض WebSocket)

### 2. نصب پکیج

پکیج از قبل نصب شده است. اگر نیاز به نصب مجدد دارید:

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

### 3. تنظیمات محیط (.env)

فایل `.env` باید شامل تنظیمات زیر باشد:

```env
BROADCAST_DRIVER=pusher

PUSHER_APP_ID=sabok
PUSHER_APP_KEY=sabokkey
PUSHER_APP_SECRET=saboksecret
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=http
PUSHER_APP_CLUSTER=mt1
```

**توجه:** این تنظیمات برای محیط توسعه (development) است. در محیط تولید (production):
- از HTTPS استفاده کنید (`PUSHER_SCHEME=https`)
- کلیدها و secret را تغییر دهید
- از SSL استفاده کنید

### 4. راه‌اندازی سرور WebSocket

برای شروع سرور WebSocket، دستور زیر را اجرا کنید:

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

این دستور سرور WebSocket را روی پورت 6001 اجرا می‌کند.

**برای محیط تولید:**
- از Process Manager مانند Supervisor استفاده کنید تا سرور همیشه در حال اجرا باشد
- پیکربندی نمونه Supervisor:

```ini
[program:sabok-websockets]
command=php /path/to/sabok/artisan websockets:serve
directory=/path/to/sabok
autostart=true
autorestart=true
user=www-data
redirect_stderr=true
stdout_logfile=/path/to/sabok/storage/logs/websockets.log
```

### 5. داشبورد WebSocket

داشبورد مدیریت WebSocket در آدرس زیر در دسترس است:

```
http://127.0.0.1:8000/laravel-websockets
```

**امنیت:** این داشبورد باید در محیط تولید محافظت شود. می‌توانید در فایل `config/websockets.php` middleware مناسب تنظیم کنید.

## نحوه عملکرد

### 1. ارسال موقعیت از اپلیکیشن موبایل

اپلیکیشن موبایل (راننده) باید موقعیت خود را به API endpoint زیر ارسال کند:

```
POST /api/location/update
Authorization: Bearer {token}

{
    "latitude": 35.6892,
    "longitude": 51.3890,
    "accuracy": 10.5,
    "speed": 45.0,
    "heading": 90.0
}
```

### 2. پخش موقعیت از طریق WebSocket

هنگامی که موقعیت دریافت می‌شود، سرور به صورت خودکار event `LocationUpdated` را پخش می‌کند:

**Channel:** `driver-locations`
**Event:** `location.updated`

**داده‌های ارسالی:**
```json
{
    "driver_id": 1,
    "driver_name": "علی احمدی",
    "driver_phone": "09123456789",
    "latitude": 35.6892,
    "longitude": 51.3890,
    "speed": 45.0,
    "heading": 90.0,
    "is_online": true,
    "last_update": "2 دقیقه پیش"
}
```

### 3. دریافت موقعیت در پنل ادمین

پنل ادمین در صفحه نقشه (`/admin/map`) به صورت خودکار به WebSocket متصل می‌شود و موقعیت‌های به‌روز شده را دریافت می‌کند.

## فایل‌های مهم

### Backend

- **Event:** `app/Events/LocationUpdated.php` - Event ارسال موقعیت
- **Controller:** `app/Http/Controllers/Api/LocationController.php` - دریافت و پخش موقعیت
- **Model:** `app/Models/DriverLocation.php` - مدل ذخیره موقعیت
- **Channel:** `routes/channels.php` - تعریف کانال‌های broadcast
- **Config:** `config/websockets.php` - تنظیمات WebSocket
- **Config:** `config/broadcasting.php` - تنظیمات Broadcasting

### Frontend

- **View:** `resources/views/admin/map.blade.php` - نقشه پنل ادمین با WebSocket
- **Script:** کد JavaScript اتصال به WebSocket در همان view

## عیب‌یابی

### سرور WebSocket متصل نمی‌شود

1. اطمینان حاصل کنید که سرور WebSocket در حال اجرا است:
```bash
php artisan websockets:serve
```

2. بررسی کنید که پورت 6001 باز است:
```bash
netstat -an | grep 6001
```

3. لاگ‌های WebSocket را بررسی کنید:
```bash
tail -f storage/logs/laravel.log
```

### موقعیت‌ها در نقشه به‌روز نمی‌شوند

1. Console مرورگر را باز کنید (F12) و پیام‌های WebSocket را بررسی کنید
2. در فایل `.env` تنظیمات `PUSHER_*` را بررسی کنید
3. اطمینان حاصل کنید که `BroadcastServiceProvider` در `config/app.php` فعال است

### خطای CORS

اگر با خطای CORS مواجه شدید، در `config/websockets.php` آدرس‌های مجاز را اضافه کنید:

```php
'allowed_origins' => [
    'http://localhost:8000',
    'http://127.0.0.1:8000',
],
```

## امنیت

### نکات امنیتی مهم:

1. **تغییر کلیدها در تولید:** حتماً `PUSHER_APP_KEY` و `PUSHER_APP_SECRET` را تغییر دهید

2. **استفاده از HTTPS:** در محیط تولید از HTTPS استفاده کنید

3. **محدودسازی دسترسی:** کانال `driver-locations` در حال حاضر عمومی است. برای محدود کردن دسترسی:

```php
// routes/channels.php
Broadcast::channel('driver-locations', function ($user) {
    // فقط ادمین‌ها می‌توانند به این کانال دسترسی داشته باشند
    return $user && $user->isAdmin();
});
```

4. **محافظت از داشبورد:** داشبورد WebSocket را با middleware محافظت کنید:

```php
// config/websockets.php
'middleware' => [
    'web',
    'auth',
    'admin',
],
```

## بهینه‌سازی

### برای عملکرد بهتر:

1. **استفاده از Redis:** برای مقیاس‌پذیری بهتر از Redis استفاده کنید:
```env
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
```

2. **تنظیم فاصله به‌روزرسانی:** فاصله ارسال موقعیت از اپلیکیشن موبایل را بر اساس نیاز تنظیم کنید (مثلاً هر 5 ثانیه)

3. **پاکسازی آمار قدیمی:**
```bash
php artisan websockets:clean
```

4. **استفاده از SSL/TLS:** برای امنیت بیشتر در تولید

## پشتیبانی و مستندات

- **Laravel WebSockets:** https://beyondco.de/docs/laravel-websockets
- **Pusher JS Client:** https://pusher.com/docs/channels/using_channels/client-api
- **Broadcasting در Laravel:** https://laravel.com/docs/10.x/broadcasting

## یادداشت‌های توسعه

این سیستم با استفاده از Laravel WebSockets پیاده‌سازی شده که یک جایگزین متن‌باز برای Pusher است و نیازی به سرویس خارجی ندارد. همه چیز روی سرور خودتان اجرا می‌شود.
