از Socket.IO تا SSE

سلام.

من مهدی، بک‌اند دولوپر مجموعه دیتاک هستم. در این پست قصد داریم جزئیات مهاجرت از socket.io به SSE یا server-sent events را باهم بررسی کنیم و از دلایل این مهاجرت تکنولوژی صحبت کنیم. با من همراه باشید.

در وهله اول چرا Socket.io؟

تقریبا ۴ سال پیش نیاز به ارسال نوتیفیکیشن در اپلیکیشن ما به وجود اومد. خروجی های سنگینی مثل بولتن، اکسل و… وجود داشت که به درخواست کاربر پشت پرده انجام میشد و ما نیاز به راه آسان‌تری داشتیم که این خروجی را به دست کاربر برسانیم. به این منظور تصمیم گرفتیم یک سیستم نوتیفیکیشن مبتنی بر وب سوکت  پیاده کنیم و از این طریق داده هایی مثل درصد آماده سازی خروجی، لینک دانلود و… را برای کاربر ارسال کنیم. با توجه به استک شرکت که در آن زمان PHP/Laravel بود امکان پیاده سازی یک سرویس وب سوکت بهینه در PHP وجود نداشت به همین دلیل به سمت استفاده از socket.io و node.js رفتیم.

دلایل مهاجرت از socket.io

Socket.io مزایای زیادی مثل هزینه راه اندازی کم، اتصال خودکار، قابلیت Broadcasting و… داشت اما با وجود این مزایا به مرور زمان متوجه مشکلات زیر شدیم:

  • سر بار بسیار زیاد socket.io و بهینه نبودن اجرای آن روی node.js
  • مشکل اتصال کاربران در برخی مرورگرها مثل سافاری و فایرفاکس
  • پیاده سازی پیچیده اعتبار سنجی کاربران(Auth)
  • یک طرفه بودن ارتباط نوتیفیکیشن ها

در نهایت برای رفع این مشکلات به راه حل های زیر رسیدیم:

  1. استفاده از socket.io اما روی زبان های برنامه نویسی بهینه تر مثل golang
  2. پیاده سازی یک سرویس مبتنی بر websocket یا long-polling
  3. پیاده سازی یک سرویس مبتنی بر server-sent events

Server-sent event چیست؟

قبل از بررسی راه حل ها بهتر است با sse آشنا شویم. sse یک پروتکل استاندارد ارتباط real-time است بر پایه اتصال HTTP است. از آنجاییکه این پروتکل به صورت پیشفرض داخل تمام مرورگر ها تعریف شده و ذاتا Event-driven است به راحتی در جاوا اسکریپت و در نتیجه تمام مرورگر ها قابل استفاده است. از طرفی بر خلاف وب سوکت این پروتکل یک طرفه است و فقط سرور قابلیت ارسال پیام را دارد. در مجموع این پروتکل به دلیل معماری متفاوتش بسیار سریع تر و سبک تر از پروتکل هایی مثل وب سوکت یا socket.io است.

از سوی دیگر از ضعف های این پروتکل می‌توان به موارد زیر اشاره کرد:

  • نداشتن ack؛ از آنجاییکه کلاینت قابلیت ارسال پیام را ندارد نمی‌تواند ack بفرستد.
  • نداشتن fallback؛ در صورت وجود مشکل در پروتکل هایی مثل وب سوکت قابلیت استفاده از long-polling هست که sse چنین جایگزینی را ندارد.

چرا SSE؟

برای حل مشکل کاربران در مرورگر های مختلف لازم بود از پروتکل های استاندارد وب استفاده کنیم در نتیجه گزینه استفاده مجدد از socket.io رد میشد. از سوی دیگر هر دو پروتکل وب سوکت و sse بسیار سبک تر و بهینه از socket.io بودند. بعد از بررسی تمام جنبه ها تنها مزیت وب سوکت تضمین دریافت نوتیف و دو طرفه بودن ارتباط بود.

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

ممنون از اینکه با من در این پست همراه بودید.

 

دیدگاه خود را بنویسید:

آدرس ایمیل شما نمایش داده نخواهد شد.

فوتر سایت