وبسوکت یا SSE؟ دعوا سر ترتیب رویدادهاست
خلاصهٔ کاملتر
خوزه والیم، سازندهٔ زبان Elixir، تو این مقاله جواب یه کامنت پرطرفدار Hacker News رو میده که گفته بود برای بیشتر اپها SSE (یعنی یه کانال یکطرفه که سرور روش رویداد پوش میکنه) بهعلاوهٔ Fetch کافیه، چون لِیتِنسیشون یکیه. به گفتهٔ نویسنده هر درخواست Fetch باز هم بیحالته و باید دوباره سشن رو رمزگشایی و کاربر رو از دیتابیس یا کش بیاره، ولی تو وبسوکت اتصال یه بار احراز هویت میشه و دادهی کاربر تو حافظه میمونه.
ولی نویسنده میگه اینا مزیت درجهدومن و بحث اصلی جای دیگهایه: ترتیب و درستی رویدادها. مثالش سادهست؛ یه مقاله سه تگ erlang و clojure و javascript داره. شما تگ elixir رو اضافه میکنی و همزمان یه کاربر دیگه javascript رو حذف میکنه. اگه پاسخ حذف دیرتر از راه برسه، رابط کاربری آخرش فقط erlang و clojure رو نشون میده، انگار اصلاً تگ elixir اضافه نشده.
نکتهٔ تلختر اینه که این حالت خودش درست نمیشه. والیم میگه به این نمیشه گفت eventual consistency (یعنی سیستمی که اگه آپدیت جدیدی نیاد، همهٔ نسخهها آخرش به یه مقدار میرسن)، چون صفحه میتونه بینهایت کهنه بمونه تا وقتی که رفرش کنی یا یه رویداد جدید برسه. ریشهٔ مشکل هم خود SSE نیست، بلکه رسیدن داده از دو جریان جداست؛ وبسوکت بهعلاوهٔ Fetch هم همین باگ رو داره.
راهحلها هم مجانی نیستن. میشه کاری کرد فقط یه جریان آپدیت رو تحویل بده، یعنی Fetch فقط بنویسه و کلاینت منتظر بمونه نتیجه از SSE برسه؛ ولی این یعنی داده باید از یه صف بین سرورها رد بشه و لِیتِنسی بالا میره. گزینهٔ بعدی اینه که SSE فقط بگه «داده جدید داری، رفرش کن»، که بار سرور رو زیاد میکنه و باید حواست باشه چند فچ همزمان نفرستی و درخواستهای کاربر اولویت داشته باشن.
مرتبکردن رویدادهای بیترتیب روی کلاینت هم بهنظر ساده میاد ولی نیست؛ هیچ تضمینی نداری که رویداد ساختهشدن یه منبع قبل از حذفش برسه. نویسنده اشاره میکنه برای همینه که پلتفرمهایی مثل Electric کلاً برای حل همین مسئله ساخته شدن. جمعبندیش هم اینه: هر جا چند جریان داده داری، با هم مسابقه میدن، و وبسوکت چون دوطرفهست ارزونترین پایه برای حفظ ترتیب بین کار کاربر و پاسخ سروره.
نکات کلیدی:
- بحث اصلی بین WebSocket و SSE لِیتِنسی نیست، ترتیب و درستی رویدادهاست
- هر درخواست Fetch بیحالته و سشن و کاربر رو دوباره لود میکنه؛ وبسوکت یه بار احراز هویت میشه
- Phoenix LiveView بهجای HTML، دیف تغییرات رو روی سیم میفرسته و حجم پیام رو خیلی کم میکنه
- رابط کاربری کهنه با eventual consistency توجیه نمیشه؛ تا رفرش یا رویداد بعدی همونطور میمونه
- راهحل تکجریانی روی SSE یعنی عبور نوشتنها از صف بین سرورها و لِیتِنسی بیشتر




