ساخت یه اسکوربورد زنده با Laravel Reverb
خلاصهٔ کاملتر
یانیک لینفت، تو این آموزش، ساخت یه اسکوربورد زندهٔ فوتبال به اسم Kickoff رو با Laravel Reverb نشون میده -یه سرور وبسوکت رسمی لاراول که با پروتکل Pusher کار میکنه و بدون نیاز به سرویس شخصثالث، مستقیم با Broadcasting لاراول و Echo تو فرانتاند جفت میشه. اول دلیل انتخاب وبسوکت بهجای پولینگ رو توضیح میده: تو پولینگ، مرورگر هر چندثانیه یهبار از سرور میپرسه چیزی عوض شده یا نه -که یعنی برای یه بازی بدون گل هم مدام درخواست میفرسته، و تازگی داده هم به فاصلهٔ پول بستگی داره. تو وبسوکت، کلاینت فقط یهبار وصل میشه و سرور فقط وقتی خبری هست پیام میفرسته؛ هزینهش نگهداشتن یه عالمه اتصال بازه، ولی برای یه اسکوربورد که بیشتر دقایقش ساکته، این هزینه میارزه.
مدل دادهها سهتاست: Game که وضعیت و کرونومتر بازی رو نگه میداره (با یه enum رشتهای برای وضعیتهایی مثل scheduled، live، half_time و...)، Result که دو تا امتیازو نگه میداره، و GameEvent که هر اتفاق (گل، کارت، تعویض) رو ثبت میکنه. یه نکتهٔ ظریف اینه که current_minute و clock_started_at دو ستون جدا نگه داشته میشن، تا کرونومتر تو خود مرورگر تیک بزنه بدون اینکه لازم باشه هر ثانیه یه پیام جدا پخش بشه.
برای پخش، هر سه رویداد (تغییر امتیاز، تغییر وضعیت، ثبت رویداد بازی) بهجای ShouldBroadcast معمولی از ShouldBroadcastNow استفاده میکنن، چون بار داده کوچیکه و تأخیر صفبندی اینجا بهصرفه نیست. نکتهٔ جالب اینه که هر رویداد رو دو کانال همزمان پخش میشه -یه کانال اختصاصی برای همون بازی (game.{id}) و یه کانال عمومی برای کل اسکوربورد - با یه dispatch:
class ScoreUpdated implements ShouldBroadcastNow
{
public function broadcastOn(): array
{
return [
new Channel("game.{$this->game->id}"),
new Channel('scoreboard.live'),
];
}
}هر دو کانال عمومیان (چون امتیاز فوتبال مخفی نیست)، برای همین نیازی به تعریف مجوز تو routes/channels.php نیست. متد broadcastWith هم پیلود رو به همون فیلدهایی که رابط کاربری واقعاً بهشون نیاز داره محدود میکنه -مثلاً اسم تیمها چون وسط بازی عوض نمیشن، اصلاً تو پیلود نیستن.
آخرین نکتهٔ مهم اینه که این رویدادها از داخل کنترلر dispatch نمیشن، بلکه از داخل observer مدلها (مثلاً متد saved() تو ResultObserver). اینطوری، هر مسیری که یه Result رو ذخیره کنه -چه از کنترلر، چه یه جاب پسزمینه، چه یه دستور artisan- خودبهخود باعث پخش میشه، بدون اینکه کسی لازم باشه یادش بمونه.
نکات کلیدی:
- بهجای پولینگ، از Laravel Reverb (سرور وبسوکت با پروتکل Pusher) برای پخش آنی امتیاز استفاده شده
- current_minute و clock_started_at جدا نگه داشته میشن تا کرونومتر تو مرورگر تیک بزنه بدون پخش هر ثانیه
- رویدادها با ShouldBroadcastNow (نه صفبندیشده) و همزمان رو یه کانال اختصاصی بازی و یه کانال عمومی اسکوربورد پخش میشن
- broadcastWith پیلود رو کوچیک نگه میداره؛ dispatch هم از داخل observer مدل انجام میشه، نه کنترلر، تا هیچ مسیری فراموش نشه




