فرض کنید می خواهیم سرویسی را پیاده سازی کنیم که کاربر ها (کلاینت ها) بتوانند با هم تماس تصویری و یا صوتی برقرار کنند. یک ایده اولیه برای پیاده سازی همچین سرویسی استفاده از معماری کلاینت سروری عادی است. استفاده از یک سرور که کلاینت ها به آن متصل شده، محتوا را از دستگاه مربوطه دریافت کنند و آن را به سرور ارسال کنند. سپس سرور آن را به کلاینت دیگر منتقل کند. این کار سربار زیادی ممکن است داشته باشد و عملا ارتباط بین این دو از سرعت کافی برخوردار نشود یا به عبارتی ارتباط real time نخواهیم داشت.

  • مسئله
  • WebRTC چیست؟
  • WebRTC چطور کار می کند؟
  • مولفه های WebRTC
    • Client
    • Signaling Server
    • STUN server
    • TURN server
  • پیاده سازی WebRTC با Flutter
  • منابع (برای مطالعه دقیق تر مفاهیم و پیاده سازی)

مسئله

هدف کلی از webRTC برقراری یک ارتباط real timeبین دو کلاینت (peer) است. یا به عبارتی می خواهیم سرعت انتقال داده (هر نوع داده ای، نه فقط media ) به حداکثر برسد و یا بعبارتی از حداقل واسطه های میانی برای این انتقال استفاده شود.

WebRTC چیست؟

webRTC محموعه ای پروتکل ها و  API ها است که توانایی برقراری ارتباط real time بین دو peer در شبکه (مثلا اینترنت) را فراهم می کنند. webRTC اجازه می دهد که ارتباط صوتی و یا تصویری در داخل یک صفحه وب با ارتباط peer-to-peer و بدون نیاز به نصب هیچ پلاگین یا برنامه اضافه ای انجام شود.

WebRTC چطور کار می کند؟

به طور عادی برای برقرار ارتباط بین دو peer در شبکه، نیاز به یک سرور میانی هست که یک peer به آن متصل شده و داده‌ی خود را به آن بفرستد و سپس peer دوم بعد از متصل شدن به سرور داده را دریافت کند. دلیل آن این است که peer اول نمی تواند به طور عادی یک connection به peer دوم بزند. چون peer ها در اینترنت لزوما Public IP ندارند و پشت Firewall و یا NAT هستند که هر نوع درخواست connection از بیرون را رد می کنند.

ولی با این حال یک peer می تواند به یک web server که Public IP دارد، درخواست connection بزند، و از سرور جواب دریافت کند. اگر این peer پشت یک router قرار داشته باشد، بعد ارسال درخواست از peer به سرور، router بسته های ارسالی از peer را دریافت کرده، به جای IP مبدا peer (که تنها در شبکه داخلی معتبر است)، Public IP  خودش را قرار می دهد و بسته را به سمت سرور ارسال می کند. ( همچنین یکی از پورت هایش را بعنوان پورت مبدا این بسته قرار می دهد.)

برای دریافت جواب از سرور، router به نوعی (بسته به مدل NAT)،‌ در حافظه اش ذخیره می کند (موقتا) که هر بسته ای از این پس از IP سرور به سمت پورت اختصاص داده شده ارسال شد، به سمت peer هدایت شود. به این کار روتر NAT می گویند. یکی از عواقب این کار این است که هرکسی نمی تواند از شبکه خارجی به peer که در شبکه داخلی پشت router قرار دارد connection بزند.

آشنایی دقیق تر با NAT و انواع

کاری که در webRTC انحام می شود این است که دو peer ابتدا به یک سرور درخواست می فرستند. سرور از هر کدام از این دو peer یک ip و port می بیند که می توان با آن ها به peer ها  وصل شد. حال کافیست peer اول به ip و port ای که سرور از peer دوم می بیند متصل شود و بالعکس. به این صورت دو peer با یک دیگر متسقیما ارتباط خواهند داشت (بدون اینکه از سروری میانی برای ادامه ارتباط استفاده شود.)

مولفه های WebRTC

برای برقراری اتصال webRTC به این مولفه ها نیاز هست:

Client

Signaling Server

peer ها برای برقراری ارتباط ابتدا خود را به این سرور معرفی می کنند. این سرور لیستی از کلاینت ها و شیوه ارتباط آن ها و اطلاعات بیشتری از آن ها را در خود دارد. (برای آشنایی دقیق با پروتکل های ارتباطی این لینک را ببینید).

پسpeer ها باید خود  را ابتدا به این سرور بشناسانند. این سرور می تواند بسته با توجه به عملکردش به هر نحوی پیاده سازی شود. (کاری که انجام می دهد مهم است، پروتکل های استفاده شده یا پیاده سازی ها می توانند متفاوت باشند.)

webRTC در فلاتر

STUN server

peer ها از این سرور برای فهمیدن IPو port عمومی خود استفاده می کنند. (برای این کار کافیست که peer ها یک connection به این سرور بزنند).

همچنین این سرور ممکن است چک کند که آیا امکان برقراری ارتباط مستقیم بین دو peer وجود دارد یا خیر.

webRTC در فلاتر

TURN server

اگر دو peer نتوانند مستقیما به هم متصل شوند. این سرور بعنوان سرور میانی برای انتقال داده بین peer ها استفاده می شود. در این حالت دیگر عملا اتصال P2P نداریم.

webRTC در فلاتر

پیاده سازی WebRTC با Flutter

در فلاتر برای پیاده سازی webRTC (بخش کلاینت) می توان از flutter_webrtc استفاده کرد. اما این کتابخانه documentation ضعیفی دارد و احتمالا برای اتصال به مشکلات زیادی بخوریم.

من پیاده سازی‌ای از این کتاب خانه در این ریپازیتوری قرار داده ام:

https://github.com/MohsenDehghankar/flutter_webrtc_client

که توضیحات لازم برای راه اندازی webRTC گفته شده است.

  • برای برقراری یک تماس تصویری، علاوه بر کد بالا بعنوان کلاینت نیاز هست که signaling server نیز داشته باشیم که از این ریپازیتوری  می توان استفاده کرد.
  • برای سرور TURN و STUN هم می توان از coturn server استفاده کرد که نحوه راه اندازی آن در اینجا آمده است.

برای آشنایی با API های WebRTC می توانید به این آدرس مراجعه کنید.

منابع (برای مطالعه دقیق تر مفاهیم و پیاده سازی)

https://support.medialooks.com/hc/en-us/articles/360000213312-%D0%95nvironment-signaling-STUN-and-TURN-servers

https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Connectivity

https://www.frozenmountain.com/developers/blog/webrtc-nat-traversal-methods-a-case-for-embedded-turn

درباره نیلوا

ایران،تهران

ناحیه نوآوری شریف

بلوار جواد اکبری

برج فناوری بنتک

T: 09150773830
E: admin[@]nilva.ir