یک چت زنده ساده نزدیک بود این نسخه را به نابودی بکشاند

یک سیستم چت زنده ساده تقریباً آخرین نسخه منتشر شده من را خراب کرد.

ساده به نظر می‌رسد. کاربران نزدیک را نشان می‌دهید و اجازه می‌دهید با هم صحبت کنند. اما واقعیت فنی بسیار دشوارتر است. من مجبور بودم چت زنده را با موقعیت مکانی (geolocation) و یک سیستم امتیازدهی متصل کنم. این کار پیچیدگی بسیار زیادی در زیرساخت ایجاد کرد.

معماری:

• Frontend: React و TypeScript. • Backend: Node.js با Express و WebSockets. • Database: PostgreSQL برای کاربران و امتیازها. • Cache: Redis برای نشست‌های (sessions) فعال و وضعیت حضور (presence).

مشکل موقعیت مکانی (Geolocation)

تطبیق کاربران بر اساس مکان کار آسانی نیست. من مجبور بودم حالات مرزی (edge cases) زیادی را مدیریت کنم:

  • ذخیره طول و عرض جغرافیایی.
  • استفاده از افزونه‌های Postgres برای پرس‌وجوی فاصله.
  • مدیریت کاربرانی که اجازه دسترسی به مکان را رد می‌کنند.
  • مدیریت داده‌های قدیمی (stale) زمانی که کاربر بدون باز کردن اپلیکیشن جابه‌جا می‌شود.

اگر دوباره این کار را انجام می‌دادم، جمع‌آوری موقعیت مکانی را از بخش تطبیق (matching) به سرویس‌های مختلف جدا می‌کردم.

واقعیت چت زنده

WebSockets قابلیت‌های بلادرنگ (real-time) را به ارمغان می‌آورند، اما آشفتگی نیز به همراه دارند. من از Redis pub/sub برای ارسال پیام‌ها بین سرورهای مختلف استفاده کردم.

سخت‌ترین بخش‌ها این‌ها بودند:

  • پاکسازی اتصالات زمانی که کاربران به‌طور غیرمنتظره قطع می‌شوند.
  • جلوگیری از ارسال پیام به اتاق‌هایی که کاربر از آن‌ها خارج شده است.
  • مدیریت اتصال مجدد بدون ایجاد نشست‌های شبح‌وار (ghost sessions).

یاد گرفتم که استفاده از یک ماشین حالت (state machine) رسمی بهتر از استفاده از پرچم‌های (flags) ساده است.

سیستم امتیازدهی

امتیازدهی تا زمانی که آن را نمی‌سازید، پیش‌پاافتاده به نظر می‌رسد. من باید اطمینان حاصل می‌کردم که:

  • کاربران نتوانند به یک نشست یکسان دو بار امتیاز دهند.
  • امتیازها برای نمایش در پروفایل به سرعت تجمیع شوند.
  • داده‌ها در سراسر اپلیکیشن یکپارچه باقی بمانند.

من از محدودیت‌های یکتا (unique constraints) روی شناسه نشست‌ها (session IDs) برای جلوگیری از تکرار استفاده کردم و میانگین‌ها را برای حفظ عملکرد، کش کردم.

درس‌های آموخته شده

اگر امروز دوباره این را بازسازی کنم، سه چیز را تغییر خواهم داد:

۱. جدا کردن بخش تطبیق و چت به ماژول‌های مجزا. ۲. استفاده از مدل‌سازی صریح برای وضعیت‌های اتصال WebSocket. ۳. اضافه کردن لاگ‌ها و متریک‌های بهتر برای چت و تطبیق از روز اول.

ساخت نرم‌افزار مجموعه‌ای از تصمیمات کوچک است. این تصمیمات تعیین می‌کنند که سیستم شما تمیز و منظم باشد یا شکننده.

آیا تا به حال یک چت زنده یا یک سیستم تطبیق ساخته‌اید؟ شما چه کار متفاوتی انجام می‌دادید؟

منبع: https://dev.to/jaeger974/simple-live-chat-almost-sank-this-release-2pn7