ارسال داده بین مرورگرها با کانال های داده WebRTC

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

این مشکلات را می توان با استفاده از WebRTC RTCDataChannel API برای انتقال مستقیم داده ها از یک همتا به دیگری کاهش داد. این مقاله اصول اولیه نحوه راه‌اندازی و استفاده از کانال‌های داده و همچنین موارد استفاده رایج در وب امروز را پوشش می‌دهد.

چرا کانال داده دیگری؟

ما رویدادهای WebSocket ، AJAX و Server Sent را داریم. چرا به کانال ارتباطی دیگری نیاز داریم؟ WebSocket دو طرفه است، اما همه این فناوری ها برای ارتباط با یا از یک سرور طراحی شده اند.

RTCDataChannel رویکرد متفاوتی دارد:

  • با RTCPeerConnection API کار می کند که اتصال همتا به همتا را امکان پذیر می کند. این می تواند منجر به تاخیر کمتری شود - بدون سرور واسطه و "هپ" کمتر.
  • RTCDataChannel از پروتکل انتقال کنترل جریان (SCTP) استفاده می‌کند، که امکان پیکربندی معنایی تحویل قابل تنظیم را فراهم می‌کند، تحویل خارج از نظم و پیکربندی ارسال مجدد.

RTCDataChannel اکنون با پشتیبانی SCTP روی دسکتاپ و اندروید در گوگل کروم، اپرا و فایرفاکس در دسترس است.

یک هشدار: سیگنالینگ، STUN و TURN

WebRTC ارتباط همتا به همتا را فعال می‌کند، اما همچنان به سرورهایی برای سیگنال‌دهی برای تبادل رسانه و ابرداده‌های شبکه برای راه‌اندازی اتصال همتا نیاز دارد.

WebRTC با NAT ها و فایروال ها با موارد زیر مقابله می کند:

برای اطلاعات بیشتر در مورد نحوه عملکرد WebRTC با سرورهای سیگنالینگ و شبکه، به WebRTC در دنیای واقعی مراجعه کنید: STUN، TURN و سیگنالینگ .

قابلیت ها

API RTCDataChannel از مجموعه ای انعطاف پذیر از انواع داده ها پشتیبانی می کند. API برای تقلید دقیق WebSocket طراحی شده است و RTCDataChannel از رشته ها و همچنین برخی از انواع باینری در جاوا اسکریپت مانند Blob ، ArrayBuffer و ArrayBufferView پشتیبانی می کند. این انواع می توانند هنگام کار با انتقال فایل و بازی چند نفره مفید باشند.

RTCDataChannel می‌تواند در حالت نامعتبر و نامرتب (مشابه پروتکل دیتاگرام کاربر یا UDP)، حالت مطمئن و مرتب (مشابه با پروتکل کنترل انتقال یا TCP) و حالت‌های قابل اعتماد جزئی کار کند:

  • حالت قابل اطمینان و سفارش داده شده، انتقال پیام ها و همچنین ترتیب تحویل آنها را تضمین می کند . این کار سربار اضافی می گیرد، بنابراین به طور بالقوه این حالت را کندتر می کند.
  • حالت نامطمئن و نامرتب تضمین نمی کند که هر پیامی به طرف مقابل برسد و یا اینکه با چه ترتیبی به آنجا می رسد . این کار سربار را حذف می کند و به این حالت اجازه می دهد بسیار سریعتر کار کند.
  • حالت مطمئن جزئی، انتقال پیام را تحت شرایط خاصی تضمین می کند، مانند مهلت ارسال مجدد یا حداکثر مقدار ارسال مجدد . ترتیب پیام ها نیز قابل تنظیم است.

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

در اینجا یک جدول مفید از شبکه مرورگر با عملکرد بالا توسط ایلیا گریگوریک آمده است:

TCP UDP SCTP
قابلیت اطمینان قابل اعتماد غیر قابل اعتماد قابل تنظیم
تحویل سفارش داده شده بدون سفارش قابل تنظیم
انتقال بایت گرا پیام گرا پیام گرا
کنترل جریان آره خیر آره
کنترل تراکم آره خیر آره

در مرحله بعد، یاد می گیرید که چگونه RTCDataChannel برای استفاده از حالت مطمئن و منظم یا غیرقابل اعتماد و نامرتب پیکربندی کنید.

پیکربندی کانال های داده

چندین دمو ساده از RTCDataChannel به صورت آنلاین وجود دارد:

در این مثال‌ها، مرورگر یک اتصال همتا با خود ایجاد می‌کند، سپس یک کانال داده ایجاد می‌کند و از طریق اتصال همتا پیامی ارسال می‌کند. سپس یک کانال داده ایجاد می کند و پیام را در امتداد اتصال همتا ارسال می کند. در نهایت پیام شما در کادر سمت دیگر صفحه ظاهر می شود!

کد برای شروع با این کوتاه است:

const peerConnection = new RTCPeerConnection();

// Establish your peer connection using your signaling channel here
const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

شی dataChannel از یک اتصال همتا از قبل ایجاد شده ایجاد می شود. می تواند قبل یا بعد از سیگنال دهی ایجاد شود. سپس یک برچسب برای متمایز کردن این کانال از کانال های دیگر و مجموعه ای از تنظیمات پیکربندی اختیاری ارسال می کنید:

const dataChannelOptions = {
  ordered: false, // do not guarantee order
  maxPacketLifeTime: 3000, // in milliseconds
};

همچنین می توان یک گزینه maxRetransmits (تعداد دفعاتی که باید قبل از شکست امتحان شود) اضافه کرد، اما شما فقط می توانید maxRetransmits یا maxPacketLifeTime را تعیین کنید، نه هر دو را. برای معناشناسی UDP، maxRetransmits روی 0 تنظیم کنید و به false ordered . برای اطلاعات بیشتر، به این RFCهای IETF مراجعه کنید: پروتکل انتقال کنترل جریان و پروتکل انتقال کنترل جریان پروتکل قابلیت اطمینان جزئی .

  • ordered : اگر کانال داده باید سفارش را تضمین کند یا خیر
  • maxPacketLifeTime : حداکثر زمان برای تلاش و ارسال مجدد یک پیام ناموفق
  • maxRetransmits : حداکثر تعداد دفعاتی که می‌توان یک پیام ناموفق را دوباره ارسال کرد
  • protocol : اجازه می دهد تا از یک پروتکل فرعی استفاده شود که اطلاعات متا را به برنامه ارائه می دهد
  • negotiated : اگر روی درست تنظیم شود، راه‌اندازی خودکار یک کانال داده در طرف دیگر را حذف می‌کند و راه خود را برای ایجاد یک کانال داده با همان شناسه در طرف دیگر فراهم می‌کند.
  • id : به شما امکان می‌دهد شناسه خود را برای کانال ارائه دهید که فقط می‌تواند در ترکیب با مجموعه negotiated روی true استفاده شود)

تنها گزینه‌هایی که اکثر مردم باید از آن استفاده کنند سه گزینه اول هستند: ordered ، maxPacketLifeTime و maxRetransmits . با SCTP (اکنون توسط همه مرورگرهایی که از WebRTC پشتیبانی می کنند استفاده می شود) قابل اطمینان و مرتب به طور پیش فرض درست است. اگر می‌خواهید کنترل کامل از لایه برنامه داشته باشید، استفاده از غیرقابل اعتماد و نامرتب منطقی است، اما در بیشتر موارد، قابلیت اطمینان جزئی مفید است.

توجه داشته باشید که مانند WebSocket، RTCDataChannel هنگام برقراری اتصال، بسته شدن، یا خطاها، و هنگامی که پیامی از طرف دیگر دریافت می کند، رویدادها را فعال می کند.

آیا ایمن است؟

رمزگذاری برای تمام اجزای WebRTC اجباری است. با RTCDataChannel ، تمام داده‌ها با امنیت لایه انتقال داده‌گرام (DTLS) ایمن می‌شوند. DTLS مشتق شده از SSL است، به این معنی که داده های شما به اندازه استفاده از هر اتصال استاندارد مبتنی بر SSL ایمن خواهد بود. DTLS استاندارد شده و در تمام مرورگرهایی که از WebRTC پشتیبانی می کنند تعبیه شده است. برای اطلاعات بیشتر، Wireshark wiki را ببینید.

طرز فکر خود را در مورد داده ها تغییر دهید

مدیریت حجم زیادی از داده ها می تواند یک نقطه دردناک در جاوا اسکریپت باشد. همانطور که توسعه دهندگان Sharefest اشاره کردند، این نیاز به تفکر در مورد داده ها به روشی جدید داشت. اگر فایلی را منتقل می کنید که بزرگتر از مقدار حافظه ای است که در دسترس دارید، باید به فکر راه های جدیدی برای ذخیره این اطلاعات باشید. همانطور که در ادامه می بینید، اینجاست که فناوری هایی مانند FileSystem API وارد عمل می شوند.

یک برنامه اشتراک گذاری فایل بسازید

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

برای انجام یک انتقال موفقیت آمیز چندین مرحله لازم است:

  1. با استفاده از File API یک فایل را در جاوا اسکریپت بخوانید.
  2. با RTCPeerConnection یک ارتباط همتا بین مشتریان ایجاد کنید.
  3. با RTCDataChannel یک کانال داده بین مشتریان ایجاد کنید.

هنگام تلاش برای ارسال فایل از طریق RTCDataChannel چندین نکته وجود دارد که باید در نظر بگیرید:

  • اندازه فایل: اگر اندازه فایل نسبتاً کوچک است و می توان آن را به صورت یک Blob ذخیره و بارگذاری کرد، می توانید با استفاده از File API در حافظه بارگذاری کنید و سپس فایل را از طریق یک کانال قابل اعتماد همانطور که هست ارسال کنید (البته به خاطر داشته باشید که مرورگرها محدودیت هایی برای حداکثر اعمال می کنند. اندازه انتقال). با بزرگتر شدن اندازه فایل، همه چیز پیچیده تر می شود. هنگامی که مکانیزم chunking مورد نیاز است، تکه‌های فایل بارگیری می‌شوند و به همتای دیگری ارسال می‌شوند، همراه با متادیتا chunkID تا همتا بتواند آنها را تشخیص دهد. توجه داشته باشید که در این مورد، همچنین باید تکه‌ها را ابتدا در فضای ذخیره‌سازی آفلاین ذخیره کنید (مثلاً با استفاده از FileSystem API) و تنها زمانی که فایل را به طور کامل در اختیار دارید، آن را در دیسک کاربر ذخیره کنید.
  • اندازه تکه: اینها کوچکترین "اتم" داده برای برنامه شما هستند. خرد کردن لازم است زیرا در حال حاضر محدودیت اندازه ارسال وجود دارد (اگرچه این مشکل در نسخه بعدی کانال‌های داده برطرف خواهد شد). توصیه فعلی برای حداکثر اندازه قطعه 64 کیلوبایت است.

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

function saveFile(blob) {
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'File Name';
  link.click();
};

این برنامه های اشتراک گذاری فایل در PubShare و GitHub از این تکنیک استفاده می کنند. آنها هر دو منبع باز هستند و پایه خوبی برای یک برنامه اشتراک گذاری فایل مبتنی بر RTCDataChannel هستند.

پس چه کاری می توانید انجام دهید؟

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

  • به اشتراک گذاری فایل نظیر به نظیر همانطور که قبلا توضیح داده شد
  • بازی چند نفره، همراه با فناوری‌های دیگر، مانند WebGL، همانطور که در BananaBread موزیلا دیده می‌شود.
  • تحویل محتوا توسط PeerCDN دوباره اختراع شده است، چارچوبی که دارایی های وب را از طریق ارتباطات داده همتا به همتا ارائه می دهد.

روش ساخت اپلیکیشن ها را تغییر دهید

اکنون می‌توانید برنامه‌های جذاب‌تری را با استفاده از اتصالات با کارایی بالا و با تأخیر کم از طریق RTCDataChannel ارائه کنید. چارچوب‌هایی مانند PeerJS و PubNub WebRTC SDK ، پیاده‌سازی RTCDataChannel آسان‌تر می‌کنند و API اکنون از پشتیبانی گسترده در سراسر پلتفرم‌ها برخوردار است.

ظهور RTCDataChannel می تواند طرز فکر شما را در مورد انتقال داده در مرورگر تغییر دهد.

اطلاعات بیشتر