افزودن همکاری بلادرنگ به اپ ساخته‌شده با هوش مصنوعی (بدون خراب کردن کار دیگران)

همکاری بلادرنگ وقتی دو نفر همزمان یک اپ را ویرایش می‌کنند، از هم می‌پاشد — تغییرات یک نفر بی‌سروصدا ناپدید می‌شود، رونویسی می‌شود، یا با چیزی که نفر دیگر می‌بیند در تناقض قرار می‌گیرد. سه حالت خرابی و سه راه‌حل، که یکی‌یکی ساخته می‌شوند، مشکل را حل می‌کنند.

وقتی دو نفر همزمان یک اپ را ویرایش می‌کنند چه اتفاقی می‌افتد؟

همکاری بلادرنگ همان چیزی است که جلوی رونویسی شدن کار دو نفر روی هم را می‌گیرد، وقتی هر دو همزمان روی داده‌های یک اپ کار می‌کنند — اگر نادیده‌اش بگیرید، ذخیره‌ی نفر دوم می‌تواند بی‌سروصدا کار نفر اول را پاک کند. این اتفاقی است که برای یک تیم افتاد.

یک کاربر یک لیست کار مشترک با تیمش ساخته بود. عصر جمعه، دو نفر از اعضای تیم همزمان آن را باز کردند. هر دو این را می‌دیدند:

  • وظیفه ۱: خرید مایحتاج
  • وظیفه ۲: تماس با مامان
  • وظیفه ۳: تنظیم جلسه

عضو A گزینه‌ی «خرید مایحتاج» را تیک زد. عضو B مورد «تعمیر روتر» را اضافه کرد. هر دو روی ذخیره کلیک کردند.

وقتی عضو A صفحه را رفرش کرد، این را دید:

  • وظیفه ۱: خرید مایحتاج (تیک‌خورده)
  • وظیفه ۲: تماس با مامان
  • وظیفه ۳: تنظیم جلسه

«تعمیر روتر» ناپدید شده بود. کار عضو B از بین رفته بود.

این یک برخورد است: نوشتن همزمان، و ناپدید شدن تغییرات یک نفر. شنیدنش شبیه یک ویژگی است — اما در واقع راه‌حلی برای جلوگیری از از دست رفتن داده است. بدون آن، اپ شما همان لحظه‌ای که دو نفر همزمان به آن دست بزنند، خراب می‌شود.

رایج‌ترین باگ‌های همکاری بلادرنگ چه هستند؟

همکاری بلادرنگ معمولاً به سه شکل رایج خراب می‌شود: یک نوشته بی‌سروصدا گم می‌شود، صفحه‌ای داده‌ی قدیمی نشان می‌دهد، یا دو نفر سر از دو واقعیت متناقض درمی‌آورند. هرکدام شکل متفاوتی دارد و هرکدام راه‌حل خودش را می‌خواهد.

خرابی ۱: نوشته‌ی گم‌شده (از دست رفتن بی‌سروصدای داده)

دو نفر همزمان ذخیره می‌کنند. ذخیره‌ی دوم روی اولی رونویسی می‌شود. نفر دوم می‌بیند تغییرش اعمال شد، نفر اول می‌بیند… هیچ‌چیز. یا صفحه را رفرش می‌کند و متعجب می‌ماند کارش کجا رفته.

داستان واقعی: یک برنامه‌ریز عروسی و دستیارش روی لیست مهمانان کار می‌کردند. دستیار سه پاسخ RSVP اضافه می‌کند، درست همان‌موقع که برنامه‌ریز دو نفر را «قطعی» علامت می‌زند. علامت‌های برنامه‌ریز ناپدید می‌شوند. تا وقتی که برنامه‌ریز در تماس‌های پیگیری دوباره حساب می‌کند، کسی متوجه نمی‌شود — و حالا دارد از کسانی که قبلاً بله گفته‌اند، دوباره دعوت می‌کند.

بیشتر اپ‌های واقعی این را با ذخیره‌ی هر ضربه‌ی کلید حل می‌کنند، نه فقط با کلیک روی «ذخیره». Google Sheets، Notion و Figma همه این‌طورند. اپ شما هم به همین رفتار نیاز دارد.

خرابی ۲: رفرش قدیمی (دیدن داده‌ی کهنه)

نفر A یک وظیفه را ویرایش می‌کند. نفر B صفحه را باز دارد و نسخه‌ی قدیمی را می‌بیند. او بر اساس داده‌ی کهنه تغییری اعمال می‌کند. حالا یک تعارض هست که برای هیچ‌کدام قابل دیدن نیست.

داستان واقعی: یک ارزیاب بیمه و یک پیمانکار روی یک ادعای خسارت کار می‌کردند. ارزیاب «هزینه‌ی تعمیر تخمینی: ۳۰۰۰ دلار» را بر اساس عکس‌های جدید به «۵۰۰۰ دلار» تغییر می‌دهد. صفحه‌ی پیمانکار هنوز ۳۰۰۰ دلار نشان می‌دهد. او فرم تأیید را برای ۳۰۰۰ دلار ارسال می‌کند. بعدها، تعارض را کشف می‌کنند.

بدون به‌روزرسانی بلادرنگ، هر دو نفر فکر می‌کنند روی یک نسخه‌ی یکسان کار می‌کنند. اما این‌طور نیست.

خرابی ۳: تناقض زنجیره‌ای (دو واقعیت)

یک کاربر یک رکورد را حذف می‌کند. کاربر دیگری در همان لحظه جزئیات همان رکورد را می‌بیند. یکی «حذف‌شده» می‌بیند، دیگری هنوز رکورد کامل را می‌بیند. حالا هرکدام بر اساس واقعیتی متفاوت عمل می‌کنند.

داستان واقعی: یک هماهنگ‌کننده‌ی داوطلبان یک شیفت را «لغوشده» علامت می‌زند. داوطلب هنوز صفحه را رفرش نکرده و شیفت را همچنان «باز» می‌بیند. او شروع می‌کند به جذب نیرو برای همان شیفت. چند ساعت بعد، دو نفر برای شیفتی سر می‌رسند که هرگز واقعی نبوده است.

چطور باگ‌های همکاری بلادرنگ را رفع کنیم؟

آن‌ها را به‌ترتیب و یکی‌یکی رفع کنید: با ذخیره‌ی تدریجی، تعارض‌های نوشتن را شناسایی کنید؛ رفرش‌ها را بدون از دست دادن ویرایش‌های محلی ادغام کنید؛ و در نهایت، به‌جای پنهان کردن تعارض‌ها، آن‌ها را آشکار کنید. لازم نیست همان روز اول همکاری بلادرنگ را بی‌نقص حل کنید.

راه‌حل ۱: شناسایی تعارض‌های نوشتن (ذخیره‌ی تدریجی)

کاری کنید هر تغییر بلافاصله ذخیره شود، نه فقط با کلیک روی «ذخیره». این مهم‌ترین راه‌حل است.

وقتی کاربر یک فیلد را ویرایش می‌کند، آن را همان لحظه به دیتابیس بفرستید. یک نشانگر کوچک «ذخیره شد» یا نقطه‌ای نشان دهید که با پایان همگام‌سازی ناپدید می‌شود. اگر نفر دومی همزمان ذخیره کند، دیتابیس شما باید این‌طور ببیندش:

  • تغییر نفر A اول اعمال می‌شود.
  • تغییر نفر B دوم اعمال می‌شود.
  • نفر B برنده می‌شود (قانون «آخرین نوشته برنده است»).

این روش خشن اما صادقانه است: دست‌کم یک نفر می‌بیند تغییرش ثبت نشده و می‌تواند دوباره انجامش دهد.

درخواست از سازنده: ذخیره را با هر ضربه‌ی کلید یا ۲ ثانیه پس از توقف تایپ کاربر فعال کنید، نه با یک دکمه‌ی «ذخیره». یک نشانگر همگام‌سازی نشان دهید. تستش کنید: اپ خود را در دو پنجره‌ی مرورگر باز کنید و یک فیلد یکسان را ویرایش کنید. یک تغییر باید به‌شکل قابل‌مشاهده روی دیگری رونویسی شود.

راه‌حل ۲: رفرش بدون از دست دادن ویرایش‌های محلی

اگر هر ۵ ثانیه دیتابیس را poll می‌کنید (یا از طریق WebSocket به‌روزرسانی push می‌کنید)، داده‌های جدید را طوری ادغام کنید که ویرایش‌های جاری کاربر را از بین نبرد.

راه غلط: رفرش کامل صفحه. تمام ویرایش‌های محلی از بین می‌روند.

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

درخواست از سازنده: وقتی داده‌ی تازه از دیتابیس می‌گیرید، آن را ادغام کنید: ویرایش‌های محلی را نگه دارید، بقیه را به‌روز کنید. در یک فریم‌ورک واقعی معمولاً این کار در دو خط کد انجام می‌شود. تستش کنید: در یک پنجره یک فیلد را ویرایش کنید، همزمان در پنجره‌ی دیگر فیلدی متفاوت را ویرایش کنید. هر دو تغییر باید باقی بمانند.

راه‌حل ۳: واقعیت را واضح نشان دهید

وقتی تعارضی یا داده‌ی کهنه‌ای وجود دارد، آن را نشان دهید. پنهانش نکنید.

نمونه‌ها:

  • «این وظیفه توسط شخص دیگری حذف شد. بازگردانی؟»
  • «کسی درحالی‌که شما در حال تایپ بودید، سه مورد به این لیست اضافه کرد. [موارد جدید را ببینید]»
  • «شما در حال دیدن نسخه‌ای از ۲ دقیقه پیش هستید. برای دیدن آخرین نسخه رفرش کنید.»

درخواست از سازنده: هنگام بارگذاری، بررسی کنید آیا داده‌ای که نشان می‌دهید مهر زمانی دارد یا نه. اگر عمرش بیش از ۳۰ ثانیه است و کاربر می‌خواهد ویرایش کند، یک هشدار نشان دهید و دوباره داده را بگیرید. اگر لیستی نشان می‌دهید، دکمه‌ی «رفرش» را طوری نمایش دهید که به‌عنوان یک اقدام کاربری منطقی باشد، نه نشانه‌ی یک خرابی.

وقتی همکاری بلادرنگ کاملاً حل شده باشد، چه شکلی دارد؟

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

  1. هر ضربه‌ی کلید بلافاصله ذخیره می‌شود — منتظر یک دکمه نمانید.
  2. تعارض‌ها با یک قاعده حل می‌شوند — اگر هر دویمان یک کلمه‌ی یکسان را ویرایش کنیم، سیستم یک برنده انتخاب می‌کند (معمولاً «آخرین نوشته برنده است»، یا یک پیام تعارض به شما نشان داده می‌شود).
  3. به‌روزرسانی‌ها فوراً می‌رسند — از طریق WebSocket، Server-Sent Events، یا دیتابیسی که push می‌کند (مثل Firebase).

بیشتر اپ‌ها همان روز اول به این نیاز ندارند. از ذخیره‌ی تدریجی شروع کنید (راه‌حل ۱). وقتی دو نفر همزمان از اپ استفاده می‌کنند، poll + ادغام را اضافه کنید (راه‌حل ۲). فقط اگر تعارض‌ها واقعاً دردسرساز شدند، push فوری را اضافه کنید.

قبل از انتشار، چطور همکاری بلادرنگ را تست کنیم؟

قبل از انتشار، سه تست را در دو پنجره‌ی مرورگر اجرا کنید: تست ذخیره‌ی همزمان، تست داده‌ی کهنه، و تست رفرش. هرکدام یک نتیجه‌ی روشن قبول یا رد دارد.

تست ۱: تست ذخیره‌ی همزمان

  • اپ خود را در دو پنجره‌ی مرورگر باز کنید.
  • در پنجره‌ی ۱، فیلد X را ویرایش و ذخیره کنید.
  • در پنجره‌ی ۲، بلافاصله بعد فیلد Y را ویرایش و ذخیره کنید.
  • هر دو پنجره را رفرش کنید.
  • قبول: هر دو ویرایش موجودند. رد: یکی از ویرایش‌ها گم شده است.

تست ۲: تست داده‌ی کهنه

  • اپ را در پنجره‌ی ۱ باز کنید. دستش نزنید.
  • در پنجره‌ی ۲، چیز بزرگی را تغییر دهید (یک ردیف اضافه/حذف کنید، یک عنوان را عوض کنید).
  • به پنجره‌ی ۱ برگردید (که هنوز داده‌ی قدیمی را نشان می‌دهد).
  • سعی کنید نسخه‌ی کهنه‌ی پنجره‌ی ۱ را ویرایش کنید.
  • قبول: یک هشدار می‌گیرید یا داده‌ها به‌درستی ادغام می‌شوند. رد: شما تغییر پنجره‌ی ۲ را رونویسی می‌کنید.

تست ۳: تست رفرش

  • کار مهمی در حال انجام داشته باشید (فرمی نیمه‌پر، پیامی پیش‌نویس).
  • صفحه را رفرش کنید.
  • قبول: کار شما هنوز آنجاست. رد: از بین رفته است.

آیا باید با هر ضربه‌ی کلید ذخیره کنید یا منتظر دکمه‌ی ذخیره بمانید؟

با هر ضربه‌ی کلید ذخیره کنید. همین یک تصمیم، ۸۰ درصد راه رسیدن به همکاری بلادرنگ را طی می‌کند — بقیه‌اش فقط آشکار کردن آن و مدیریت برخوردهاست.

کاربران امروز همین را انتظار دارند. Gmail، Google Docs، Slack — هر اپ مدرنی این کار را می‌کند. اپ شما هم باید همین‌طور باشد.

اولین کاری که باید انجام دهید: کاری کنید هر تغییر خودکار ذخیره شود. یک نشانگر کوچک نشان دهید («در حال ذخیره…» و بعد ناپدید می‌شود). ببینید وقتی دو نفر همزمان ویرایش می‌کنند چه اتفاقی می‌افتد. اگر تغییر یک نفر ناپدید شد، آن راه‌حل بعدی شماست. حل یک مشکل در هر بار، بهتر از تلاش برای ساختن همکاری بی‌نقص در همان روز اول است.