WebRTC. ویدئو کنفرانس در مرورگر چت چند کاربره با استفاده از چت صوتی WebRTC Webrtc

مقدمه چت تصویری P2P روشن است پایگاه WebRTCجایگزینی برای اسکایپ و سایر وسایل ارتباطی است. عناصر اصلی چت تصویری p2p مبتنی بر WebRTC یک مرورگر و یک سرور تماس است. چت های تصویری P2P چت های تصویری همتا به همتا هستند که در آن سرور در انتقال جریان های اطلاعاتی شرکت نمی کند. اطلاعات به طور مستقیم بین مرورگرهای کاربران (همتایان) بدون هیچ گونه انتقال داده می شود برنامه های اضافی. علاوه بر مرورگرها، چت های ویدیویی p2p از سرورهای تماسی استفاده می کنند که برای ثبت نام کاربران، ذخیره داده های مربوط به آنها و اطمینان از جابجایی بین کاربران طراحی شده اند. مرورگرهایی که از آخرین فناوری‌های WebRTC و HTML5 پشتیبانی می‌کنند، پیام‌های متنی فوری و انتقال فایل و همچنین ارتباط صوتی و تصویری را از طریق شبکه‌های IP ارائه می‌کنند.

بنابراین، چت، چت وب، چت صوتی و تصویری در یک رابط وب، IMS، VoIP خدماتی هستند که ارتباطات آنلاین را از طریق شبکه های سوئیچ بسته ترکیبی ارائه می کنند. به عنوان یک قاعده، خدمات ارتباطی یا نیاز به نصب برنامه های مشتری بر روی دستگاه های کاربر (کامپیوتر، تلفن های هوشمند و غیره) یا نصب افزونه ها و برنامه های افزودنی در مرورگرها دارند. سرویس ها شبکه های ارتباطی خاص خود را دارند که اکثر آنها بر اساس معماری سرویس گیرنده-سرور ساخته شده اند.

سرویس‌های ارتباطی برنامه‌هایی غیر از IMS هستند که کانال‌های صوتی، ویدئو، داده و متن در آنها یکپارچه نیستند. در شبکه های هر سرویس، . لازم به ذکر است که این برنامه ها نمی توانند به طور همزمان در چندین شبکه ارتباطی کار کنند. برنامه ها معمولاً نمی توانند با یکدیگر ارتباط برقرار کنند و نیاز به نصب برنامه جداگانه برای هر شبکه ارتباطی دارند.

مشکل یکپارچه سازی خدمات ارتباطی بلادرنگ (چت، تلفن، ویدئو کنفرانس)، یعنی. ادغام صدا، ویدئو، کانال های داده و دسترسی به آنها با استفاده از یک برنامه کاربردی (مرورگر) را می توان در چت های ویدئویی نظیر به نظیر یا p2p (همتا به همتا، نقطه به نقطه) بر اساس پروتکل WebRTC حل کرد. اساساً، مرورگری که از WebRTC پشتیبانی می کند به یک رابط واحد برای همه دستگاه های کاربر (کامپیوتر، تلفن های هوشمند، آی پد، تلفن های IP، تلفن های همراهو غیره) که با خدمات ارتباطی کار می کنند.

WebRTC است که اجرای تمام فناوری‌هایی را که ارتباطات بلادرنگ را ارائه می‌کنند در مرورگر تضمین می‌کند. ماهیت چت های ویدیویی p2p این است که داده های چند رسانه ای و متنی مستقیماً بین مرورگرهای کاربران (نظارت از راه دور) بدون مشارکت سرور یا برنامه های اضافی منتقل می شوند. بنابراین، مرورگرها نه تنها به تقریباً همه دسترسی دارند منابع اطلاعاتاینترنت که بر روی سرورها ذخیره می‌شوند، اما به وسیله‌ای برای دسترسی به تمام خدمات ارتباطی و خدمات پستی بلادرنگ تبدیل می‌شوند (پست صوتی، پست الکترونیک، اس ام اس و ...)

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

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

بنابراین، فناوری جدید برای ارتباطات تحت وب (چت p2p، چت ویدیویی) پروتکل WebRTC است. WebRTC همراه با HTML5، CSS3 و جاوا اسکریپت به شما اجازه می دهد تا برنامه های مختلف وب ایجاد کنید. WebRT برای سازماندهی ارتباطات وب (شبکه های همتا به همتا) در زمان واقعی با استفاده از معماری همتا به همتا طراحی شده است. چت‌های P2P مبتنی بر WebRTC انتقال فایل و همچنین ارتباط متنی، صوتی و تصویری را بین کاربران از طریق اینترنت تنها با استفاده از مرورگرهای وب بدون استفاده از افزونه‌ها و افزونه‌های خارجی در مرورگر فراهم می‌کنند.

در چت های p2p، سرور فقط برای برقراری ارتباط p2p بین دو مرورگر استفاده می شود. برای ایجاد بخش مشتری یک چت p2p بر اساس پروتکل WebRTC، از HTML5، CSS3 و JavaScript استفاده می شود. برنامه مشتری از طریق WebRTC API با مرورگرها تعامل دارد.

WebRTC توسط سه API جاوا اسکریپت پیاده سازی می شود:

  • RTCPeerConnection؛
  • MediaStream (getUserMedia);
  • RTCDataChannel.

مرورگرها داده های رسانه را با استفاده از پروتکل SRTP که در بالای UDP اجرا می شود، انتقال می دهند. از آنجایی که NAT برای مرورگرها (کلاینت ها) پشت روترهای NAT که از اتصالات p2p از طریق اینترنت استفاده می کنند، مشکلاتی ایجاد می کند، STUN برای دور زدن مترجم های NAT استفاده می شود. STUN یک پروتکل سرویس گیرنده-سرور است که در بالای پروتکل انتقال UDP اجرا می شود. در چت های p2p معمولاً از یک سرور STUN عمومی استفاده می شود و اطلاعات دریافتی از آن برای اتصال UDP بین دو مرورگر در صورتی که پشت NAT باشند استفاده می شود.

نمونه هایی از اجرای برنامه های WebRTC (چت p2p، چت وب صوتی و تصویری):
1. چت تصویری P2P Bistri (چت تصویری با یک کلیک، چت p2p)، بر اساس WebRTC، می تواند در Bistri باز شود. Bistri بدون نصب برنامه ها و افزونه های اضافی در مرورگر کار می کند. ماهیت کار به شرح زیر است: با استفاده از پیوند مشخص شده یک چت ویدیویی p2p باز کنید، پس از ثبت نام در رابطی که باز می شود، شرکا را دعوت کنید، سپس از لیست مشتریان همتا شریکی را که آنلاین است انتخاب کنید و روی "تماس ویدیویی" کلیک کنید. " دکمه.

در نتیجه MediaStream (getUserMedia) میکروفون + وب کم را ضبط می کند و سرور پیام های سیگنالینگ را با شریک انتخاب شده مبادله می کند. پس از تبادل پیام های سیگنالینگ، PeerConnection API کانال هایی را برای انتقال جریان های صوتی و تصویری ایجاد می کند. علاوه بر این، Bistri پیام های متنی و فایل های فوری را انتقال می دهد. در شکل 1 تصویری از رابط چت ویدیویی Bistri p2p را نشان می دهد.


برنج. 1. چت تصویری P2P Bistri

2. Twelephone (چت تصویری p2p، چت p2p، SIP Twelephone) - این برنامه مشتری بر اساس HTML5 و WebRTC ساخته شده است، که به شما امکان می دهد تماس های صوتی و تصویری و همچنین ارسال پیام های متنی فوری، یعنی. Twelephone شامل چت آزمایشی p2p، چت ویدیویی و SIP Twelephone است. لازم به ذکر است که Twelephone از پروتکل SIP پشتیبانی می کند و اکنون می توانید با استفاده از حساب توییتر خود به عنوان شماره تلفن تماس های صوتی و تصویری را از تلفن های SIP برقرار و دریافت کنید. بعلاوه، پیام های متنیمی توانید از طریق میکروفون با صدا وارد شوید و برنامه تشخیص صدا متن را در خط "ارسال پیام" وارد می کند.

Twelephone یک تلفن وب مبتنی بر مرورگر است گوگل کروم، شروع از نسخه 25، بدون اضافی نرم افزار. Twelephone توسط Chris Matthieu توسعه داده شد. پشتیبان Twelephone بر روی Node.js ساخته شده است. سرور (سرور تماس) فقط برای برقراری ارتباط p2p بین دو مرورگر یا کلاینت های WebRTC استفاده می شود. برنامه Twelephone ابزارهای مجوز مخصوص به خود را ندارد، اما بر روی اتصال به یک حساب متمرکز شده است ( حساب) در توییتر.

در شکل 2 تصویری از رابط چت ویدیویی Twelephone p2p را نشان می دهد.



برنج. 2. تلفن P2P

3. چت ویدیویی گروهی p2p Conversat.io بر اساس آخرین فناوری های WebRTC و HTML5 ساخته شده است. چت ویدیویی Conversat بر اساس کتابخانه SimpleWebRTC توسعه یافته است و برای ارتباط بین حداکثر 6 مشتری همتا در یک اتاق در نظر گرفته شده است (برای ارتباط، نام اتاق مشترک برای مشتریان همتا را در خط "نام مکالمه" نشان دهید). چت تصویری P2P Conversat خدمات ارتباطی را بدون ثبت نام در سرور تماس به کاربران ارائه می دهد. در شکل شکل 3 تصویری از رابط چت ویدیویی Conversat p2p را نشان می دهد.



برنج. 3. چت تصویری گروهی P2P Conversat.io

برای شرکت در چت های ویدیویی P2P مبتنی بر WebRTC، کاربران باید مرورگری نصب کرده باشند که از پروتکل WebRTC و مشخصات HTML5 پشتیبانی می کند. در حال حاضر مرورگرهای گوگل کروم که با نسخه 25 شروع می شوند و موزیلا فایرفاکس Nightly از پروتکل WebRTC و مشخصات HTML5 پشتیبانی می کند. برنامه های WebRTC از نظر کیفیت انتقال تصویر و صدا نسبت به برنامه های فلش برتری دارند.

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

مقدمه WebRTC

WebRTC یک فناوری مرورگر محور است که به شما امکان می دهد دو کلاینت را برای انتقال داده های ویدیویی متصل کنید. ویژگی های اصلی پشتیبانی داخلی توسط مرورگرها (نیازی به فناوری های پیاده سازی شده شخص ثالث مانند adobe flash وجود ندارد) و امکان اتصال کلاینت ها بدون استفاده از سرورهای اضافی - اتصال همتا به همتا (از این پس p2p).

ایجاد یک اتصال p2p یک کار نسبتاً دشوار است، زیرا رایانه ها همیشه آدرس های IP عمومی، یعنی آدرس هایی در اینترنت ندارند. با توجه به تعداد کم آدرس های IPv4 (و برای اهداف امنیتی)، مکانیسم NAT توسعه داده شد که به شما امکان می دهد شبکه های خصوصی، به عنوان مثال، برای استفاده خانگی ایجاد کنید. بسیاری از روترهای خانگی در حال حاضر از NAT پشتیبانی می کنند و به لطف این، همه دستگاه های خانگی به اینترنت دسترسی دارند، اگرچه ارائه دهندگان اینترنت معمولاً یک آدرس IP ارائه می دهند. آدرس های IP عمومی در اینترنت منحصر به فرد هستند، اما آدرس های خصوصی این گونه نیستند. بنابراین، اتصال p2p دشوار است.

برای درک بهتر این موضوع، سه موقعیت را در نظر بگیرید: هر دو گره در یک شبکه قرار دارند (شکل 1)، هر دو گره در شبکه های مختلف (یکی به صورت خصوصی، دیگری در عمومی) (شکل 2) و هر دو گره در شبکه های خصوصی مختلف با همان آدرس های IP (شکل 3).

شکل 1: هر دو گره در یک شبکه

شکل 2: گره ها در شبکه های مختلف (یکی در خصوصی، یکی در عمومی)

شکل 3: گره ها در شبکه های خصوصی مختلف، اما با آدرس های عددی برابر

در شکل های بالا، حرف اول در نماد دو کاراکتری، نوع گره را نشان می دهد (p = peer، r = router). در تصویر اول، وضعیت مطلوب است: گره‌ها در شبکه خود به طور کامل با آدرس‌های IP شبکه شناسایی می‌شوند و بنابراین می‌توانند مستقیماً به یکدیگر متصل شوند. در شکل دوم دو شبکه متفاوت با شماره گره مشابه داریم. اینجاست که روترها (روترها) ظاهر می شوند که دارای دو هستند رابط شبکه- در داخل شبکه و خارج از شبکه شما. به همین دلیل آنها دو آدرس IP دارند. گره های معمولی تنها یک رابط دارند که از طریق آن فقط در داخل شبکه خود می توانند ارتباط برقرار کنند. اگر آنها داده ها را به فردی خارج از شبکه خود منتقل می کنند، فقط با استفاده از NAT در داخل روتر (روتر) و بنابراین برای دیگران تحت آدرس IP روتر قابل مشاهده است - این مال آنهاست. خارجیآدرس آی پی. بنابراین گره p1 دارد داخلی IP = 192.168.0.200 و خارجی IP = 10.50.200.5 و آخرین آدرس نیز برای تمام گره های دیگر در شبکه آن خارجی خواهد بود. وضعیت برای گره p2 نیز مشابه است. بنابراین، اگر فقط از آدرس های IP داخلی (خود) آنها استفاده شود، ارتباط آنها غیرممکن است. شما می توانید از آدرس های خارجی، یعنی آدرس های روتر استفاده کنید، اما از آنجایی که همه گره ها در یک شبکه خصوصی یک آدرس خارجی دارند، این کار بسیار دشوار است. این مشکل با استفاده از مکانیزم NAT قابل حل است

اگر تصمیم بگیریم گره ها را از طریق آدرس های داخلی آنها به هم متصل کنیم چه اتفاقی می افتد؟ داده ها از شبکه خارج نمی شوند. برای تقویت اثر، می توانید وضعیت نشان داده شده در شکل آخر را تصور کنید - هر دو گره آدرس های داخلی یکسانی دارند. اگر از آنها برای برقراری ارتباط استفاده کنند، هر گره با خودش ارتباط برقرار می کند.

WebRTC با استفاده از پروتکل ICE با چنین مشکلاتی با موفقیت کنار می آید، که با این حال، نیاز به استفاده از سرورهای اضافی (STUN، TURN) دارد. اطلاعات بیشتر در مورد همه اینها در زیر.

دو فاز WebRTC

برای اتصال دو گره از طریق پروتکل WebRTC (یا به سادگی RTC، اگر دو آیفون در حال ارتباط هستند)، باید مراحل اولیه را برای برقراری اتصال انجام دهید. این مرحله اول است - ایجاد یک ارتباط. مرحله دوم انتقال داده های تصویری است.

ارزش این را دارد که بلافاصله بگوییم که اگرچه فناوری WebRTC از بسیاری استفاده می کند به طرق مختلفارتباطات (TCP و UDP) و دارای سوئیچینگ انعطاف پذیر بین آنها، این فناوری است پروتکلی برای انتقال داده های اتصال ندارد. جای تعجب نیست، زیرا اتصال دو گره p2p چندان آسان نیست. بنابراین داشتن مقداری ضروری است اضافیروشی برای انتقال داده که به هیچ وجه به WebRTC مرتبط نیست. این می تواند یک انتقال سوکت، پروتکل HTTP باشد، حتی می تواند باشد پروتکل SMTPیا پست روسیه این مکانیزم انتقال اولیهداده نامیده می شود علامت. نیازی به انتقال اطلاعات زیادی نیست. تمام داده ها به صورت متنی منتقل می شوند و به دو نوع تقسیم می شوند - SDP و Ice Candidate. نوع اول برای ایجاد ارتباط منطقی و نوع دوم برای اتصال فیزیکی استفاده می شود. در ادامه بیشتر در مورد همه این موارد، اما در حال حاضر فقط مهم است که به یاد داشته باشید که WebRTC اطلاعاتی را به ما می دهد که باید به گره دیگری منتقل شوند. به محض انتقال تمام اطلاعات لازم، گره ها قادر به اتصال خواهند بود و دیگر نیازی به کمک ما نخواهد بود. بنابراین مکانیسم سیگنال دهی که باید پیاده سازی کنیم این است بصورت جداگانه، استفاده خواهد شد فقط در صورت اتصال، اما هنگام انتقال داده های ویدیویی استفاده نخواهد شد.

بنابراین، بیایید فاز اول را در نظر بگیریم - مرحله ایجاد اتصال. از چند نکته تشکیل شده است. بیایید ابتدا به این مرحله برای گره ای که اتصال را آغاز می کند و سپس برای گرهی که در انتظار است نگاه کنیم.

  • آغازگر (تماس گیرنده):
  • پیشنهاد شروع انتقال داده ویدیویی (createOffer)
  • دریافت SDP SDP شما)
  • در حال دریافت کاندیدای Ice Ice )
  • انتظار تماس (callee):
  • دریافت یک جریان رسانه محلی (شما) و تنظیم آن برای انتقال (getUserMediaStream)
  • دریافت پیشنهاد برای شروع انتقال داده های ویدئویی و ایجاد پاسخ (createAnswer)
  • دریافت شی SDP و عبور آن از مکانیسم سیگنالینگ (SDP)
  • دریافت اشیاء کاندید یخ و عبور دادن آنها از طریق مکانیسم سیگنالینگ (Ice namzet)
  • دریافت یک جریان رسانه از راه دور (خارجی) و نمایش آن بر روی صفحه (onAddStream)

تنها تفاوت در نکته دوم است.

علیرغم پیچیدگی ظاهری مراحل، در واقع سه مورد از آنها وجود دارد: ارسال جریان رسانه خود (مورد 1)، تنظیم پارامترهای اتصال (موارد 2-4)، دریافت جریان رسانه شخص دیگری (مورد 5). دشوارترین مرحله مرحله دوم است، زیرا از دو بخش تشکیل شده است: استقرار فیزیکیو منطقیاتصالات اولی نشان می دهد مسیر، که بسته ها باید در طول آن حرکت کنند تا از یک گره شبکه به گره دیگر برسند. دومی نشان می دهد پارامترهای ویدئویی/صوتی– از چه کیفیتی استفاده کنیم، از چه کدک هایی استفاده کنیم.

از نظر ذهنی، مرحله createOffer یا createAnswer باید به مراحل گذراندن اشیاء کاندید SDP و Ice متصل شود.

موجودیت‌های اصلی جریان‌های رسانه (MediaStream)

موجودیت اصلی جریان رسانه است، یعنی جریان داده های تصویری و صوتی، تصویر و صدا. دو نوع جریان رسانه وجود دارد - محلی و راه دور. محلی داده ها را از دستگاه های ورودی (دوربین، میکروفون) و از راه دور از طریق شبکه دریافت می کند. بنابراین، هر گره هم یک رشته محلی و هم یک رشته راه دور دارد. در WebRTC، یک رابط MediaStream برای استریم ها و همچنین یک زیرواسط LocalMediaStream به طور خاص برای یک جریان محلی وجود دارد. در جاوا اسکریپت فقط می توانید با اولی روبرو شوید، اما اگر از libjingle استفاده می کنید می توانید با دومی نیز روبرو شوید.

WebRTC یک سلسله مراتب نسبتاً گیج کننده در یک رشته دارد. هر جریان می تواند از چندین تراک رسانه (MediaTrack) تشکیل شده باشد که به نوبه خود می تواند از چندین کانال رسانه (MediaChannel) تشکیل شود. و همچنین ممکن است خود چندین جریان رسانه ای وجود داشته باشد.

بیایید همه چیز را به ترتیب نگاه کنیم. برای انجام این کار، اجازه دهید چند مثال را در ذهن داشته باشیم. بیایید بگوییم که ما می‌خواهیم نه تنها ویدیویی از خود، بلکه یک ویدیو از میزمان را نیز منتقل کنیم، که روی آن یک تکه کاغذ قرار دارد که قرار است چیزی روی آن بنویسیم. ما به دو ویدیو (ما + جدول) و یک صدا (ما) نیاز داریم. واضح است که ما و جدول باید به رشته های مختلف تقسیم شود، زیرا این داده ها احتمالاً به طور ضعیفی به یکدیگر وابسته هستند. بنابراین، ما دو MediaStream خواهیم داشت - یکی برای ما و دیگری برای جدول. اولی حاوی داده های صوتی و تصویری است و دومی فقط حاوی ویدیو خواهد بود (شکل 4).

شکل 4: دو جریان رسانه ای مختلف. یکی برای ما، یکی برای سفره ما

بلافاصله مشخص می‌شود که حداقل یک جریان رسانه‌ای باید دارای قابلیت حاوی داده باشد انواع متفاوت- تصویری و صوتی این در فناوری در نظر گرفته شده است و بنابراین هر نوع داده از طریق یک مسیر رسانه ای MediaTrack پیاده سازی می شود. تراک رسانه دارای نوع خاصیت خاصی است که مشخص می کند ویدیو یا صوتی باشد (شکل 5)

شکل 5: جریان های رسانه ای از تراک های رسانه ای تشکیل شده اند

چگونه همه چیز در برنامه اتفاق می افتد؟ ما دو جریان رسانه ای ایجاد خواهیم کرد. سپس دو تراک ویدیویی و یک تراک صوتی ایجاد خواهیم کرد. بیایید به دوربین ها و میکروفون دسترسی پیدا کنیم. بیایید به هر آهنگ بگوییم از کدام دستگاه استفاده کنیم. بیایید یک آهنگ ویدیویی و صوتی را به اولین جریان رسانه و یک آهنگ ویدیویی از یک دوربین دیگر به جریان رسانه دوم اضافه کنیم.

اما چگونه جریان های رسانه ای را در انتهای دیگر اتصال تشخیص دهیم؟ برای انجام این کار، هر جریان رسانه دارای یک ویژگی برچسب است - برچسب جریان، نام آن (شکل 6). تراک های رسانه نیز همین ویژگی را دارند. اگرچه در نگاه اول به نظر می رسد که ویدیو را می توان از جهات دیگری از صدا تشخیص داد.

شکل 6: جریان های رسانه ای و آهنگ ها با برچسب ها مشخص می شوند

بنابراین، اگر می‌توان آهنگ‌های رسانه را از طریق یک برچسب شناسایی کرد، پس چرا باید به جای یک جریان از دو جریان رسانه برای مثال خود استفاده کنیم؟ پس از همه، شما می توانید یک جریان رسانه را انتقال دهید، اما از آهنگ های مختلف در آن استفاده کنید. ما به یک ویژگی مهم جریان های رسانه ای رسیده ایم - آنها همگام سازیآهنگ های رسانه ای جریان‌های رسانه‌های مختلف با یکدیگر همگام‌سازی نمی‌شوند، اما در هر جریان رسانه، همه آهنگ‌ها همگام‌سازی می‌شوند به طور همزمان پخش می شوند.

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

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

در نهایت، ارزش دارد به صدای استریو فکر کنید. همانطور که می دانید صدای استریو دو صدای متفاوت است. و همچنین باید جداگانه منتقل شوند. برای این کار از MediaChannels استفاده می شود. یک تراک صوتی رسانه ای می تواند کانال های زیادی داشته باشد (مثلاً 6 کانال اگر به صدای 5+1 نیاز دارید). البته کانال هایی در داخل تراک های رسانه ای نیز وجود دارد. هماهنگ شده. برای ویدیو، معمولاً فقط از یک کانال استفاده می شود، اما می توان از چندین کانال استفاده کرد، به عنوان مثال، برای تبلیغات همپوشانی.

به طور خلاصه:ما از یک جریان رسانه ای برای انتقال داده های تصویری و صوتی استفاده می کنیم. در هر جریان رسانه، داده ها همگام می شوند. اگر نیازی به همگام سازی نداریم، می توانیم از چندین جریان رسانه استفاده کنیم. در داخل هر جریان رسانه دو نوع آهنگ رسانه وجود دارد - برای ویدیو و برای صدا. معمولاً بیش از دو آهنگ وجود ندارد، اما در صورت نیاز به انتقال چندین ویدیوی مختلف (از طرف گفتگو و میز او) ممکن است تعداد بیشتری نیز وجود داشته باشد. هر آهنگ می تواند از چندین کانال تشکیل شده باشد که معمولاً فقط برای صدای استریو استفاده می شود.

در ساده ترین حالت چت تصویری، یک جریان رسانه محلی خواهیم داشت که از دو تراک تشکیل شده است - یک تراک ویدیویی و یک تراک صوتی که هر کدام از یک کانال اصلی تشکیل شده است. تراک ویدئو مسئول دوربین، تراک صوتی برای میکروفون است و جریان رسانه محفظه هر دوی آنهاست.

توصیف جلسه (SDP)

کامپیوترهای مختلف همیشه دوربین‌ها، میکروفون‌ها، کارت‌های ویدئویی و سایر تجهیزات متفاوتی خواهند داشت. آنها گزینه های زیادی دارند. همه اینها باید برای انتقال رسانه داده بین دو گره شبکه هماهنگ شود. WebRTC این کار را به صورت خودکار انجام می دهد و ایجاد می کند شی خاص- توصیف جلسه SDP. این شی را به گره دیگری منتقل کنید، و داده های رسانه می توانند منتقل شوند. فقط هنوز ارتباطی با گره دیگری وجود ندارد.

برای این کار از هر مکانیزم سیگنالینگ استفاده می شود. SDP را می توان از طریق سوکت ها یا توسط یک شخص (آن را از طریق تلفن به گره دیگری بگویید) یا توسط Russian Post منتقل کرد. همه چیز بسیار ساده است - یک SDP آماده به شما داده می شود و باید آن را ارسال کنید. و پس از دریافت از طرف دیگر، آن را به بخش WebRTC منتقل کنید. توصیفگر جلسه به صورت متن ذخیره می شود و می تواند در برنامه های شما تغییر یابد، اما این معمولاً ضروری نیست. به عنوان مثال، هنگام اتصال تلفن دسکتاپ ↔، گاهی اوقات لازم است کدک صوتی مورد نظر را انتخاب کنید.

به طور معمول، هنگام برقراری یک اتصال، باید نوعی آدرس، مانند URL را مشخص کنید. این در اینجا ضروری نیست، زیرا از طریق مکانیسم سیگنالینگ شما خودتان داده ها را به مقصد ارسال خواهید کرد. برای اینکه به WebRTC نشان دهیم که می خواهیم یک اتصال p2p برقرار کنیم، باید تابع createOffer را فراخوانی کنیم. پس از فراخوانی این تابع و تعیین یک callback ویژه 'a، یک شی SDP ایجاد می شود و به همان callback ارسال می شود. تنها چیزی که از شما خواسته می شود این است که این شی را از طریق شبکه به گره دیگری (همکار) منتقل کنید. پس از این، داده ها از طریق مکانیسم سیگنالینگ، یعنی این شی SDP، به انتهای دیگر می رسند. این توصیفگر جلسه با این گره بیگانه است و بنابراین حاوی اطلاعات مفیدی است. دریافت این شی سیگنالی برای شروع اتصال است. بنابراین، شما باید با این موافقت کنید و تابع createAnswer را فراخوانی کنید. این یک آنالوگ کامل از createOffer است. مجدداً، توصیفگر جلسه محلی به تماس شما ارسال می شود و باید از طریق مکانیسم سیگنالینگ بازگردانده شود.

شایان ذکر است که می توانید تابع createAnswer را فقط پس از دریافت شی SDP شخص دیگری فراخوانی کنید. چرا؟ زیرا شیء SDP محلی که هنگام فراخوانی createAnswer تولید می شود، باید به شیء SDP راه دور متکی باشد. فقط در این صورت می توان تنظیمات ویدیوی خود را با تنظیمات همکار خود هماهنگ کرد. همچنین، نباید قبل از دریافت جریان رسانه محلی، createAnswer و createOffer را فراخوانی کنید - آنها چیزی برای نوشتن در شی SDP نخواهند داشت.

از آنجایی که WebRTC توانایی ویرایش یک شی SDP را دارد، پس از دریافت یک توصیفگر محلی باید آن را نصب کرد. ممکن است کمی عجیب به نظر برسد که باید آنچه را که خودش به ما داده است به WebRTC منتقل کنیم، اما این پروتکل است. هنگامی که یک دسته از راه دور دریافت می شود، باید آن را نیز نصب کنید. بنابراین، شما باید دو توصیفگر را روی یک گره نصب کنید - مال شما و شخص دیگری (یعنی محلی و راه دور).

بعد از این دست دادنگره ها از خواسته های یکدیگر اطلاع دارند. به عنوان مثال، اگر گره 1 از کدک های A و B، و گره 2 از کدک های B و C پشتیبانی می کند، از آنجایی که هر گره توصیفگرهای خود و دیگری را می شناسد، هر دو گره کدک B را انتخاب می کنند (شکل 7). منطق اتصال اکنون برقرار شده است و جریان های رسانه می توانند منتقل شوند، اما مشکل دیگری وجود دارد - گره ها هنوز فقط با یک مکانیسم سیگنالینگ متصل هستند.


شکل 7: مذاکره کدک

کاندیدای یخ

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

بنابراین، اتصال قبلا برقرار شده است (اتصال منطقی)، اما هنوز هیچ مسیری وجود ندارد که گره های شبکه بتوانند داده ها را در طول آن انتقال دهند. همه چیز به این سادگی نیست، اما بیایید ساده شروع کنیم. بگذارید گره ها در همان شبکه خصوصی باشند. همانطور که می دانیم، آنها به راحتی می توانند با استفاده از آدرس های IP داخلی خود (یا شاید برخی دیگر، اگر از TCP/IP استفاده نمی شود) به یکدیگر متصل شوند.

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

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

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

بنابراین، دو گره در یک شبکه قرار دارند (شکل 8). چگونه آنها را شناسایی کنیم؟ استفاده از آدرس های IP راه دیگری نیست. درست است، همچنان می توانید از حمل و نقل های مختلف (TCP و UDP) و پورت های مختلف استفاده کنید. این اطلاعاتی است که در شی نامزد موجود است - IP، PORT، TRANSPORT و برخی دیگر. به عنوان مثال، اجازه دهید از انتقال UDP و پورت 531 استفاده کنید.

شکل 8: دو گره در یک شبکه قرار دارند

سپس، اگر در گره p1 باشیم، WebRTC چنین شی کاندید را به ما می دهد - . این یک قالب دقیق نیست، فقط یک نمودار است. اگر در گره p2 باشیم، کاندید آن است. از طریق مکانیسم سیگنالینگ، p1 کاندید p2 را دریافت می کند (یعنی محل گره p2، یعنی IP و PORT آن). سپس p1 می تواند مستقیماً به p2 متصل شود. به عبارت صحیح تر، p1 داده ها را به 10.50.150.3:531 ارسال می کند به این امید که به p2 برسد. فرقی نمی کند این آدرس متعلق به گره p2 باشد یا واسطه. تنها نکته مهم این است که داده ها از طریق این آدرس ارسال می شوند و می توانند به p2 برسند.

تا زمانی که گره ها در یک شبکه هستند، همه چیز ساده و آسان است - هر گره فقط یک شی کاندید دارد (همیشه به معنای متعلق به خودش، یعنی مکانش در شبکه است). اما زمانی که گره ها وارد شوند، نامزدهای بیشتری وجود خواهند داشت ناهمسانشبکه های.

بیایید به یک مورد پیچیده تر برویم. یک گره در پشت روتر (به طور دقیق تر، پشت NAT) و گره دوم در همان شبکه با این روتر (به عنوان مثال، در اینترنت) قرار خواهد گرفت (شکل 9).

شکل 9: یک گره پشت NAT است، دیگری نه

این مورد راه حل خاصی برای مشکل دارد که اکنون به بررسی آن می پردازیم. روتر خانگیمعمولا شامل یک جدول NAT است. این یک مکانیسم ویژه است که به گره‌های داخل شبکه خصوصی روتر اجازه می‌دهد تا مثلاً به وب‌سایت‌ها دسترسی داشته باشند.

بیایید فرض کنیم که وب سرور مستقیماً به اینترنت متصل است، یعنی یک آدرس IP * عمومی دارد. بگذارید این گره p2 باشد. گره p1 (کلینت وب) درخواستی را به آدرس 10.50.200.10 ارسال می کند. ابتدا داده ها به روتر r1 یا بهتر است بگوییم به آن می رود داخلیرابط 192.168.0.1. پس از آن، روتر آدرس منبع (آدرس p1) را به خاطر می آورد و آن را در یک جدول NAT ویژه وارد می کند، سپس آدرس منبع را به آدرس خود تغییر می دهد (p1 → r1). علاوه بر این، به روش خودم خارجیرابط، روتر داده ها را مستقیماً به وب سرور p2 ارسال می کند. وب سرور داده ها را پردازش می کند، یک پاسخ تولید می کند و آن را پس می فرستد. r1 را به روتر می فرستد، زیرا در آدرس برگشتی قرار دارد (روتر آدرس را با آدرس خود جایگزین کرد). روتر داده ها را دریافت می کند، به جدول NAT نگاه می کند و داده ها را به گره p1 ارسال می کند. روتر در اینجا به عنوان یک واسطه عمل می کند.

اگر چندین گره از شبکه داخلی به طور همزمان به شبکه خارجی دسترسی داشته باشند چه می شود؟ چگونه روتر متوجه خواهد شد که پاسخ را برای چه کسی ارسال کند؟ این مشکل با استفاده از پورت ها. هنگامی که روتر آدرس میزبان را با آدرس خود جایگزین می کند، پورت را نیز جایگزین می کند. اگر دو گره به اینترنت دسترسی داشته باشند، روتر پورت های منبع آنها را جایگزین می کند ناهمسان. سپس، هنگامی که بسته از وب سرور به روتر باز می گردد، روتر توسط پورت متوجه می شود که بسته به چه کسی اختصاص داده شده است. مثال زیر.

بیایید به فناوری WebRTC یا به طور دقیق تر، به بخشی از آن که از پروتکل ICE استفاده می کند (از این رو نامزدهای Ice) بازگردیم. گره p2 یک نامزد دارد (موقعیت آن در شبکه 10.50.200.10 است) و گره p1 که در پشت روتر با NAT قرار دارد، دو نامزد خواهد داشت - محلی (192.168.0.200) و کاندید روتر (10.50.200.5). اولین مورد مفید نیست، اما با این وجود ایجاد شده است، زیرا WebRTC هنوز چیزی در مورد گره راه دور نمی داند - ممکن است در همان شبکه باشد یا نباشد. نامزد دوم مفید خواهد بود و همانطور که می دانیم پورت (برای عبور از NAT) نقش مهمی ایفا خواهد کرد.

یک ورودی در جدول NAT تنها زمانی ایجاد می شود که داده ها از شبکه داخلی خارج شوند. بنابراین، گره p1 باید ابتدا داده ها را ارسال کند و تنها پس از آن، داده های گره p2 می توانند به گره p1 برسند.

در تمرین هر دو گرهپشت NAT خواهد بود. برای ایجاد یک ورودی در جدول NAT هر روتر، هاست ها باید چیزی را به میزبان راه دور ارسال کنند، اما این بار نه اولی نمی تواند به دومی برسد و نه بالعکس. این به این دلیل است که گره ها آدرس IP خارجی خود را نمی دانند و ارسال داده به آدرس های داخلی بی معنی است.

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

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

STUN و TURN سرورها

هنگام راه اندازی WebRTC، باید سرورهای STUN و TURN موجود را مشخص کنید، که از این پس سرورهای ICE را فراخوانی خواهیم کرد. اگر سرورها مشخص نشده باشند، فقط گره های موجود در همان شبکه (که بدون NAT به آن متصل هستند) می توانند متصل شوند. بلافاصله شایان ذکر است که برای شبکه های 3g استفاده از سرورهای TURN اجباری است.

STUN سرورصرفاً یک سرور در اینترنت است که آدرس برگشتی، یعنی آدرس گره فرستنده را برمی گرداند. میزبان پشت روتر با سرور STUN تماس می گیرد تا از NAT عبور کند. بسته ای که به سرور STUN آمد حاوی آدرس منبع - آدرس روتر، یعنی آدرس خارجی گره ما است. این آدرس STUN است که سرور آن را پس می فرستد. بنابراین، گره آدرس IP خارجی خود و پورتی را که از طریق آن از طریق شبکه قابل دسترسی است، دریافت می کند. سپس، WebRTC از این آدرس برای ایجاد یک نامزد اضافی (آدرس و پورت روتر خارجی) استفاده می کند. اکنون یک ورودی در جدول NAT روتر وجود دارد که به بسته های ارسال شده به روتر در پورت مورد نیاز اجازه می دهد تا به گره ما برسند.

بیایید با یک مثال به این روند نگاه کنیم.

مثال (عملکرد سرور STUN)

سرور STUN با s1 نشان داده می شود. روتر مانند قبل از طریق r1 و گره از طریق p1 است. شما همچنین باید جدول NAT را نظارت کنید - ما آن را به عنوان r1_nat نشان می دهیم. علاوه بر این، این جدول معمولا حاوی رکوردهای زیادی از گره های مختلف زیرشبکه است - آنها داده نمی شوند.

بنابراین، در ابتدا یک جدول خالی r1_nat داریم.

جدول 2: سرصفحه بسته

Node p1 این بسته را به روتر r1 می فرستد (مهم نیست چگونه، زیرشبکه های مختلف می توانند از آن استفاده کنند فن آوری های مختلف). روتر باید آدرس منبع Src IP را جایگزین کند، زیرا آدرس مشخص شده در بسته بدیهی است که برای یک زیرشبکه خارجی مناسب نیست؛ علاوه بر این، آدرس هایی از چنین محدوده ای رزرو شده اند و هیچ آدرسی در اینترنت چنین آدرسی ندارد. روتر یک جایگزین در بسته ایجاد می کند و ایجاد می کند ورودی جدیددر جدول شما r1_nat. برای انجام این کار، او باید یک شماره پورت پیدا کند. به یاد بیاورید که از آنجایی که چندین میزبان در یک زیرشبکه می توانند به یک شبکه خارجی دسترسی داشته باشند، جدول NAT باید ذخیره شود اطلاعات تکمیلی، به طوری که روتر می تواند تعیین کند که کدام یک از این چندین گره برای بسته برگشتی از سرور است. اجازه دهید روتر با پورت 888 بیاید.

هدر بسته تغییر کرد:

جدول 4: جدول NAT با یک ورودی جدید به روز شده است

در اینجا آدرس IP و پورت زیرشبکه دقیقاً مشابه بسته اصلی است. در واقع هنگام پست بکینگ باید راهی برای بازیابی کامل آنها داشته باشیم. آدرس IP برای شبکه خارجی آدرس روتر است و پورت به آدرسی که روتر اختراع کرده است تغییر کرده است.

پورت واقعی که گره p1 اتصال را می پذیرد، البته 35777 است، اما سرور داده ها را به ساختگیپورت 888 که توسط روتر به 35777 واقعی تغییر خواهد کرد.

بنابراین، روتر آدرس منبع و پورت را در هدر بسته جایگزین کرد و یک ورودی به جدول NAT اضافه کرد. اکنون بسته از طریق شبکه به سرور، یعنی گره s1 ارسال می شود. در ورودی، s1 دارای بسته زیر است:

Src IP Src PORT مقصد IP مقصد PORT
10.50.200.5 888 12.62.100.200 6000

جدول 5: بسته دریافتی سرور STUN

در مجموع، سرور STUN می داند که یک بسته از آدرس 10.50.200.5:888 دریافت کرده است. حالا سرور این آدرس را پس می فرستد. ارزش این را دارد که در اینجا توقف کنیم و نگاهی دیگر به آنچه که اخیراً نگاه کردیم بیاندازیم. جداول بالا گزیده ای از آن هستند سرتیتربسته، اصلا از آن نیست محتوا. ما در مورد محتوا صحبت نکردیم، زیرا آنقدر مهم نیست - به نوعی در پروتکل STUN توضیح داده شده است. اکنون علاوه بر عنوان، محتوا را نیز در نظر خواهیم گرفت. این ساده خواهد بود و حاوی آدرس روتر - 10.50.200.5:888 است، اگرچه ما آن را از سرتیتربسته بندی این اغلب انجام نمی شود؛ پروتکل ها معمولاً به اطلاعات مربوط به آدرس گره ها اهمیت نمی دهند؛ فقط مهم است که بسته ها به مقصد مورد نظر خود تحویل داده شوند. در اینجا ما به پروتکلی نگاه می کنیم که مسیری را بین دو گره ایجاد می کند.

بنابراین اکنون یک بسته دوم داریم که در جهت مخالف حرکت می کند:

جدول 7: سرور STUN یک بسته با این محتوا ارسال می کند

سپس، بسته در سراسر شبکه حرکت می کند تا زمانی که به رابط خارجی روتر r1 برسد. روتر متوجه می شود که بسته برای آن در نظر گرفته نشده است. او چگونه این را می فهمد؟ این فقط توسط پورت قابل تعیین است. او از پورت 888 برای اهداف شخصی خود استفاده نمی کند، بلکه از آن برای مکانیسم NAT استفاده می کند. بنابراین، روتر به این جدول نگاه می کند. به ستون External PORT نگاه می کند و به دنبال خطی می گردد که با Dest PORT از بسته ورودی، یعنی 888 مطابقت داشته باشد.

IP داخلی پورت داخلی IP خارجی پورت خارجی
192.168.0.200 35777 10.50.200.5 888

جدول 8: جدول NAT

ما خوش شانسیم، چنین خطی وجود دارد. اگر ما بدشانس بودیم، بسته به سادگی دور انداخته می شد. اکنون باید بدانید که کدام گره در زیرشبکه باید این بسته را ارسال کند. نیازی به عجله نیست، بیایید بار دیگر اهمیت پورت ها را در این مکانیسم یادآوری کنیم. در همان زمان، دو گره در زیر شبکه می توانند درخواست ها را به شبکه خارجی ارسال کنند. سپس، اگر روتر برای اولین گره پورت 888 را ارائه کند، برای گره دوم با پورت 889 می آید. بیایید فرض کنیم که این اتفاق افتاده است، یعنی جدول r1_nat به شکل زیر است:

جدول 10: روتر جایگزین آدرس گیرنده می شود

Src IP Src PORT مقصد IP مقصد PORT
12.62.100.200 6000 192.168.0.200 35777

جدول 11: روتر آدرس گیرنده را تغییر داد

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

بعدش چی؟ فایده این همه چیست؟ یک مزیت ورودی در جدول r1_nat است. اگر اکنون کسی بسته ای را با پورت 888 به روتر r1 ارسال کند، روتر این بسته را به گره p1 ارسال می کند. این یک گذرگاه باریک کوچک به گره پنهان p1 ایجاد کرد.

از مثال بالا می توانید ایده ای از نحوه عملکرد NAT و ماهیت یک سرور STUN دریافت کنید. به طور کلی، مکانیسم ICE و سرورهای STUN/TURN دقیقاً در جهت غلبه بر محدودیت‌های NAT هستند.

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

سرور TURN یک سرور STUN بهبود یافته است. از اینجا باید فوراً حذف کنید که هر سرور TURN می تواند به عنوان سرور STUN نیز کار کند. با این حال، مزایایی نیز وجود دارد. اگر ارتباط p2p غیرممکن باشد (مثلاً در شبکه های 3g)، سرور به حالت رله سوئیچ می کند، یعنی به عنوان یک واسطه کار می کند. البته، ما در آن زمان در مورد هیچ p2p صحبت نمی کنیم، اما خارج از مکانیسم ICE، گره ها فکر می کنند که مستقیماً در حال ارتباط هستند.

در چه مواردی سرور TURN ضروری است؟ چرا سرور STUN کافی وجود ندارد؟ واقعیت این است که چندین نوع NAT وجود دارد. آنها آدرس IP و پورت را به همان روش جایگزین می کنند، اما برخی از آنها محافظت اضافی در برابر "جعل" در آنها تعبیه شده است. به عنوان مثال، در متقارنجدول NAT 2 پارامتر دیگر - IP و پورت میزبان راه دور را ذخیره می کند. یک بسته از شبکه خارجی تنها در صورتی از طریق NAT به شبکه داخلی منتقل می شود که آدرس منبع و پورت با موارد ثبت شده در جدول مطابقت داشته باشند. بنابراین، ترفند با سرور STUN شکست می خورد - جدول NAT آدرس و پورت سرور STUN را ذخیره می کند و هنگامی که روتر بسته ای را از همکار WebRTC دریافت می کند، آن را به دلیل "جعل" بودن دور می اندازد. از سرور STUN نیامده است.

بنابراین، در مواردی که هر دو طرف در عقب هستند، یک سرور TURN مورد نیاز است متقارن NAT (هر کدام به خود).

خلاصه ای مختصر

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

  • جریان رسانه ای
    • داده های ویدیویی و صوتی در جریان های رسانه ای بسته بندی می شوند
    • جریان‌های رسانه، آهنگ‌های رسانه‌ای را که تشکیل می‌دهند همگام‌سازی می‌کنند
    • جریان های رسانه های مختلف با یکدیگر همگام نیستند
    • جریان‌های رسانه‌ای می‌توانند محلی و از راه دور باشند، محلی معمولاً به دوربین و میکروفون متصل می‌شود، جریان‌های راه دور داده‌ها را به صورت رمزگذاری شده از شبکه دریافت می‌کنند.
    • دو نوع آهنگ رسانه وجود دارد - برای ویدیو و برای صدا.
    • آهنگ های رسانه ای قابلیت روشن/خاموش شدن را دارند
    • آهنگ های رسانه از کانال های رسانه ای تشکیل شده است
    • آهنگ‌های رسانه کانال‌های رسانه‌ای را که تشکیل می‌دهند همگام‌سازی می‌کنند
    • جریان های رسانه ای و تراک های رسانه ای دارای برچسب هایی هستند که می توان آنها را از هم تشخیص داد
  • دسته جلسه
    • توصیفگر جلسه برای اتصال منطقی دو گره شبکه استفاده می شود
    • توصیفگر جلسه اطلاعات مربوط به آن را ذخیره می کند راه های موجودرمزگذاری داده های صوتی و تصویری
    • WebRTC از مکانیزم سیگنال دهی خارجی استفاده می کند - وظیفه ارسال توصیفگرهای جلسه (sdp) بر عهده برنامه است.
    • مکانیسم اتصال منطقی شامل دو مرحله است - پیشنهاد (پیشنهاد) و پاسخ (پاسخ)
    • ایجاد توصیفگر جلسه بدون استفاده از جریان رسانه محلی در مورد پیشنهاد غیرممکن است و بدون استفاده از توصیفگر جلسه از راه دور در مورد پاسخ غیرممکن است.
    • توصیفگر حاصل باید به پیاده سازی WebRTC داده شود و فرقی نمی کند که این توصیفگر از راه دور یا محلی از همان پیاده سازی WebRTC دریافت شود.
    • امکان ویرایش جزئی توصیفگر جلسه وجود دارد
  • نامزدهای
    • یخ کاندید آدرس یک گره در شبکه است
    • آدرس گره می تواند متعلق به شما باشد یا می تواند آدرس روتر یا سرور TURN باشد
    • همیشه نامزدهای زیادی وجود دارد
    • نامزد شامل آدرس IP، پورت و نوع حمل و نقل (TCP یا UDP) است.
    • از کاندیداها برای ایجاد ارتباط فیزیکی بین دو گره در یک شبکه استفاده می شود
    • نامزدها همچنین باید از طریق مکانیسم سیگنالینگ ارسال شوند
    • نامزدها همچنین باید به پیاده سازی WebRTC منتقل شوند، اما فقط به پیاده سازی های راه دور
    • در برخی از پیاده‌سازی‌های WebRTC، نامزدها تنها پس از تنظیم یک توصیفگر جلسه قابل انتقال هستند
  • STUN/TURN/ICE/NAT
    • NAT مکانیزمی برای دسترسی به یک شبکه خارجی است
    • روترهای خانگی از جدول NAT ویژه پشتیبانی می کنند
    • روتر آدرس‌های موجود در بسته‌ها را جایگزین می‌کند - اگر بسته به یک شبکه خارجی می‌رود، آدرس منبع را با آدرس خود و آدرس گیرنده را با آدرس میزبان در شبکه داخلی، اگر بسته از یک شبکه خارجی آمده است، جایگزین می‌کند.
    • برای ارائه دسترسی چند کاناله به یک شبکه خارجی، NAT از پورت ها استفاده می کند
    • ICE - NAT Traversal Engine
    • سرورهای STUN و TURN - سرورهای دستیار برای پیمایش NAT
    • سرور STUN به شما امکان می دهد ورودی های لازم را در جدول NAT ایجاد کنید و همچنین آدرس خارجی میزبان را برمی گرداند.
    • سرور TURN مکانیسم STUN را تعمیم می دهد و باعث می شود همیشه کار کند
    • در بدترین موارد، سرور TURN به عنوان یک واسطه (رله) استفاده می شود، یعنی p2p به یک اتصال مشتری-سرور-کلینت تبدیل می شود.

امروزه WebRTC فناوری «داغ» برای پخش صدا و تصویر در مرورگرها است. فناوری‌های محافظه‌کار مانند HTTP Streaming و Flash برای توزیع محتوای ضبط‌شده (ویدئو برحسب تقاضا) مناسب‌تر هستند و از نظر زمان واقعی و پخش آنلاین به طور قابل توجهی از WebRTC پایین‌تر هستند. که در آن حداقل تأخیر ویدیو مورد نیاز است تا به بینندگان اجازه دهد آنچه را که در حال رخ دادن است به صورت زنده ببینند.

امکان ارتباط بلادرنگ با کیفیت بالا از خود معماری WebRTC می آید، جایی که پروتکل UDP برای انتقال جریان های ویدئویی استفاده می شود، که مبنای استاندارد برای انتقال ویدئو با حداقل تاخیر است و به طور گسترده در سیستم های ارتباطی بلادرنگ استفاده می شود.

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

دلیل خوب دیگر برای امتحان WebRTC این است که قطعاً یک روند است. امروز هر اندروید مرورگر کروماز این فناوری پشتیبانی می کند که میلیون ها دستگاه را برای تماشای پخش بدون نصب نرم افزار یا تنظیمات اضافی تضمین می کند.

به منظور آزمایش فناوری WebRTC در عمل و اجرای یک برنامه ساده پخش آنلاین، ما از نرم افزار سرور Flashphoner WebRTC Media & Broadcasting Server استفاده کردیم. ویژگی ها توانایی پخش جریان های WebRTC در حالت یک به چند و همچنین پشتیبانی از دوربین های IP و سیستم های نظارت تصویری از طریق پروتکل RTSP را بیان می کنند. در این بررسی ما بر روی پخش های وب وب و ویژگی های آنها تمرکز خواهیم کرد.

نصب WebRTC Media & Broadcasting Server

برای اینکه سیستم های ویندوزهیچ نسخه سروری وجود نداشت و من نمی‌خواستم یک ماشین مجازی مانند VMWare+Linux نصب کنم، بنابراین می‌توانم پخش آنلاین را در خانه آزمایش کنم. کامپیوتر ویندوزنتیجه نداد. برای صرفه جویی در زمان، ما تصمیم گرفتیم نمونه ای از میزبانی ابری مانند این را انتخاب کنیم:

Centos x86_64 نسخه 6.5 بدون نرم افزار از پیش نصب شده در مرکز داده آمستردام بود. بنابراین، تنها چیزی که در اختیار داریم دسترسی سرور و ssh به آن است. برای کسانی که با آن آشنا هستند دستورات کنسوللینوکس، نصب یک سرور WebRTC وعده می دهد که ساده و بدون دردسر باشد. پس کاری که ما انجام دادیم:

1. دانلود آرشیو:

$wget https://site/download-wcs5-server.tar.gz

2. باز کردن بسته بندی:

$tar -xzf download-wcs5-server.tar.gz

3. نصب کنید:

$cd FlashphonerWebCallServer

در حین نصب، آدرس IP سرور را وارد کنید: XXX.XXX.XXX.XXX

4. لایسنس را فعال کنید:

$cd /usr/local/FlashphonerWebCallServer/bin

$./activation.sh

5. سرور WCS را راه اندازی کنید:

$server شروع سرور وب تماس

6. گزارش را بررسی کنید:

$tail - f /usr/local/FlashphonerWebCallServer/logs/flashphoner_manager.log

7. بررسی کنید که این دو فرآیند در جای خود هستند:

$ps aux | grep Flashphoner

مراحل نصب کامل شده است.

آزمایش پخش آنلاین WebRTC

آزمایش پخش ها امری ساده بود. علاوه بر سرور، یک سرویس گیرنده وب نیز وجود دارد که از ده ها فایل جاوا اسکریپت، HTML و CSS تشکیل شده و در مرحله نصب توسط ما در پوشه /var/www/html مستقر شده است. تنها کاری که باید انجام می شد این بود که آدرس IP سرور را در پیکربندی flashphoner.xml وارد کنید تا مشتری وب بتواند از طریق HTML5 Websockets با سرور ارتباط برقرار کند. بیایید روند آزمایش را شرح دهیم.

1. صفحه مشتری آزمایشی index.html را در مرورگر کروم باز کنید:

2. برای شروع پخش، باید روی دکمه "شروع" در وسط صفحه کلیک کنید.
قبل از انجام این کار، باید مطمئن شوید که وب کم متصل و آماده استفاده است. هیچ الزام خاصی برای وب کم وجود ندارد؛ به عنوان مثال، ما از یک دوربین استاندارد تعبیه شده در لپ تاپ با رزولوشن 1280x800 استفاده کردیم.

مرورگر کروم قطعاً درخواست دسترسی به دوربین و میکروفون را می کند تا کاربر متوجه شود که ویدیوی او به سرور اینترنت ارسال می شود و اجازه می دهد.

3. رابط نشان دهنده پخش موفقیت آمیز جریان ویدئو از دوربین به سرور WebRTC است. در گوشه سمت راست بالا، یک نشانگر نشان می‌دهد که جریان به سرور می‌رود؛ در گوشه پایین دکمه «توقف» برای توقف ارسال ویدیو وجود دارد.

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

در برنامه های کاربردی واقعی مانند وبینارها، سخنرانی ها، پخش ویدئوهای آنلاین یا تلویزیون تعاملی، توسعه دهندگان باید توزیع این شناسه را بین گروه های خاصی از بینندگان پیاده سازی کنند تا بتوانند به جریان های مورد نظر متصل شوند، اما این منطق برنامه است. . WebRTC Media & Broadcasting Server بر آن تأثیر نمی گذارد، بلکه فقط ویدیو را توزیع می کند.

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

نتایج آزمایش سرور پخش آنلاین WebRTC

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

در مورد کیفیت، توجه داریم که گاهی اوقات مکعب ها را می توان با حرکات تشخیص داد. این با ماهیت کدک VP8 و هدف اصلی آن - ارائه ارتباطات ویدیویی بلادرنگ با کیفیت قابل قبول و بدون تاخیر ارتباطی مطابقت دارد.

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

کیفیت پخش برای وبینارها و پخش آنلاین کاملاً قابل قبول بود. تنها چیزی که سؤالاتی را ایجاد کرد وضوح ویدیو بود. این دوربین از 1280x800 پشتیبانی می کند، اما وضوح تصویر تست شده بسیار شبیه به 640x480 است. ظاهرا این موضوع باید با توسعه دهندگان روشن شود.

ویدیوی آزمایشی پخش شده از وب کم
از طریق سرور WebRTC

فناوری‌های برقراری تماس از طریق مرورگر سال‌هاست که وجود داشته است: Java، ActiveX، Adobe Flash...در چند سال اخیر مشخص شد که افزونه ها و ترک ماشین های مجازیآنها با راحتی (چرا باید چیزی را نصب کنم؟) و مهمتر از همه، با امنیت نمی درخشند. چه باید کرد؟ یک خروجی وجود دارد!

تا همین اواخر، شبکه‌های IP از چندین پروتکل برای تلفن IP یا ویدیو استفاده می‌کردند: SIP، رایج‌ترین پروتکل، H.323 و MGCP که از صحنه خارج می‌شوند، Jabber/Jingle (مورد استفاده در Gtalk)، Adobe RTMP* نیمه باز و البته ، اسکایپ را بسته است. پروژه WebRTC که توسط گوگل آغاز شده است، در تلاش است تا وضعیت دنیای IP و تلفن تحت وب را تغییر دهد و همه گوشی های نرم افزاریاز جمله اسکایپ WebRTC نه تنها تمام قابلیت های ارتباطی را مستقیماً در داخل مرورگر پیاده سازی می کند، که اکنون تقریباً بر روی هر دستگاهی نصب شده است، بلکه سعی می کند به طور همزمان یک مشکل کلی تر ارتباط بین کاربران مرورگر (تبادله داده های مختلف، پخش صفحه نمایش، همکاری با اسناد و ...) را حل کند. خیلی بیشتر).

WebRTC از دیدگاه توسعه دهنده وب

از دیدگاه یک توسعه دهنده وب، WebRTC از دو بخش اصلی تشکیل شده است:

  • کنترل جریان های رسانه ای از منابع محلی (دوربین، میکروفون یا صفحه نمایش). کامپیوتر محلی) توسط متد navigator.getUserMedia پیاده سازی می شود که یک شی MediaStream را برمی گرداند.
  • ارتباط همتا به همتا بین دستگاه‌هایی که جریان‌های رسانه‌ای تولید می‌کنند، از جمله تعریف روش‌های ارتباطی و انتقال مستقیم آنها - اشیاء RTCPeerConnection (برای ارسال و دریافت جریان‌های صوتی و تصویری) و RTCDataChannel (برای ارسال و دریافت داده‌ها از مرورگر).
چه کنیم؟

نحوه سازماندهی چت ویدیویی چند کاربره ساده بین مرورگرها بر اساس WebRTC با استفاده از سوکت های وب را خواهیم فهمید. ما آزمایش را در Chrome/Chromium به عنوان پیشرفته‌ترین مرورگرها از نظر WebRTC آغاز می‌کنیم، اگرچه فایرفاکس 22 که در 24 ژوئن منتشر شد، تقریباً به آنها رسیده است. باید گفت که استاندارد هنوز پذیرفته نشده است و ممکن است API از نسخه ای به نسخه دیگر تغییر کند. همه نمونه‌ها در Chromium 28 آزمایش شدند. برای سادگی، تمیز بودن کد و سازگاری بین مرورگرها را کنترل نمی‌کنیم.

MediaStream

اولین و ساده ترین مؤلفه WebRTC MediaStream است. این به مرورگر امکان دسترسی به جریان های رسانه ای از دوربین و میکروفون رایانه محلی را می دهد. در کروم، برای این کار باید تابع navigator.webkitGetUserMedia() را فراخوانی کنید (از آنجایی که استاندارد هنوز نهایی نشده است، همه توابع دارای یک پیشوند هستند و در فایرفاکس به همان تابع navigator.mozGetUserMedia() می گویند). وقتی با آن تماس می گیرید، از کاربر خواسته می شود اجازه دسترسی به دوربین و میکروفون را بدهد. ادامه تماس تنها پس از رضایت کاربر امکان پذیر خواهد بود. پارامترهای جریان رسانه مورد نیاز و دو عملکرد پاسخ به تماس به عنوان پارامتر به این تابع ارسال می شوند: در صورت موفقیت آمیز بودن دسترسی به دوربین/میکروفون، اولی فراخوانی می شود، دومی - در صورت بروز خطا. ابتدا بیایید یک فایل HTML rtctest1.html با یک دکمه و یک عنصر ایجاد کنیم:

WebRTC - اولین ویدیوی معرفی ( ارتفاع: 240 پیکسل؛ عرض: 320 پیکسل؛ حاشیه: 1 پیکسل خاکستری یکدست؛ ) getUserMedia

Microsoft CU-RTC-Web

اگر مایکروسافت بلافاصله با انتشار گزینه غیراستاندارد ناسازگار خود به نام CU-RTC-Web (html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web) فورا به ابتکار گوگل پاسخ نمی داد، مایکروسافت نمی شد. htm). اگرچه سهم اینترنت اکسپلورر که در حال حاضر کوچک بود، همچنان در حال کاهش است، تعداد کاربران اسکایپ به مایکروسافت امیدواری می‌دهد که جای گوگل را بگیرد و می‌توان فرض کرد که این استاندارد خاص در مرورگر استفاده خواهد شد. نسخه های اسکایپ. استاندارد گوگل در درجه اول بر ارتباط بین مرورگرها متمرکز است. در عین حال، بخش عمده ای از ترافیک صوتی همچنان در شبکه تلفن معمولی باقی می ماند و دروازه های بین آن و شبکه های IP نه تنها برای سهولت استفاده یا توزیع سریعتر، بلکه به عنوان وسیله ای برای کسب درآمد نیز مورد نیاز است که به بازیکنان بیشتری اجازه می دهد تا آنها را توسعه دهید. ظهور یک استاندارد دیگر ممکن است نه تنها منجر به نیاز ناخوشایند توسعه دهندگان به پشتیبانی همزمان از دو فناوری ناسازگار شود، بلکه در آینده امکان انتخاب گسترده تری از عملکردهای ممکن و راه حل های فنی موجود را نیز به کاربر می دهد. صبر کن و ببین.

فعال کردن جریان محلی

در داخل تگ های فایل HTML خود، بیایید یک متغیر سراسری برای جریان رسانه اعلام کنیم:

Var localStream = null;

اولین پارامتر متد getUserMedia باید پارامترهای جریان رسانه درخواستی را مشخص کند - به عنوان مثال، به سادگی صدا یا تصویر را فعال کنید:

Var streamConstraints = ("audio": true، "video": true); // درخواست دسترسی به صدا و تصویر

یا پارامترهای اضافی را مشخص کنید:

Var streamConstraints = ( "audio": true، "video": ( "اجباری": ( "maxWidth": "320", "maxHeight": "240"، "maxFrameRate": "5")، "اختیاری": ) )

پارامتر دوم متد getUserMedia باید به تابع callback ارسال شود که در صورت موفقیت آمیز بودن فراخوانی می شود:

تابع getUserMedia_success(stream) ( console.log("getUserMedia_success():"، جریان؛ localVideo1.src = URL.createObjectURL(stream); // جریان رسانه را به عنصر HTML متصل کنید localStream = جریان؛ // و آن را ذخیره کنید در یک متغیر جهانی برای استفاده بیشتر)

سومین پارامتر یک تابع callback است، یک کنترل کننده خطا که در صورت بروز خطا فراخوانی می شود

تابع getUserMedia_error(error) (consol.log("getUserMedia_error():"، خطا)؛ )

تماس واقعی با روش getUserMedia درخواست دسترسی به میکروفون و دوربین با فشار دادن اولین دکمه است.

تابع getUserMedia_click() (consol.log("getUserMedia_click()"); navigator.webkitGetUserMedia(streamConstraints، getUserMedia_success، getUserMedia_error)؛ )

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

خطای NavigatorUserMedia (کد: 1، PERMISSION_DENIED: 1)"

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

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

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

به دایره تپنده در نماد نشانک و نماد دوربین در سمت راست نوار آدرس توجه کنید:

RTCMediaConnection

RTCMediaConnection یک شی طراحی شده برای ایجاد و انتقال جریان های رسانه ای از طریق شبکه بین شرکت کنندگان است. علاوه بر این، این شی مسئول ایجاد یک توصیف جلسه رسانه (SDP)، به دست آوردن اطلاعات در مورد نامزدهای ICE برای عبور از NAT یا فایروال ها(محلی و با استفاده از STUN) و تعامل با سرور TURN. هر شرکت کننده باید یک RTCMediaConnection در هر اتصال داشته باشد. جریان های رسانه ای با استفاده از پروتکل رمزگذاری شده SRTP منتقل می شوند.

سرورها را تبدیل کنید

سه نوع کاندید ICE وجود دارد: میزبان، srflx و رله. میزبان حاوی اطلاعات دریافت شده به صورت محلی، srflx - اینکه گره به یک سرور خارجی (STUN) شبیه است، و رله - اطلاعات برای پروکسی کردن ترافیک از طریق سرور TURN است. اگر گره ما پشت NAT باشد، نامزدهای میزبان شامل خواهند شد آدرس های محلیو بی فایده خواهد بود، نامزدهای srflx فقط به انواع خاصی از NAT کمک می کنند و رله آخرین امید برای عبور ترافیک از طریق یک سرور میانی خواهد بود.

نمونه ای از نامزد ICE از نوع میزبان، با آدرس 192.168.1.37 و پورت udp/34022:

A=candidate:337499441 2 udp 2113937151 192.168.1.37 34022 نوع میزبان نسل 0

فرمت کلی برای تعیین سرورهای STUN/TURN:

Var servers = ( "iceServers": [ ( "url": "stun:stun.stunprotocol.org:3478")، ( "url": "turn:user@host:port"، "credential": "password") ])؛

سرورهای STUN عمومی زیادی در اینترنت وجود دارد. به عنوان مثال یک لیست بزرگ وجود دارد. متأسفانه آنها مشکلات کمی را حل می کنند. بر خلاف STUN عملاً هیچ سرور عمومی TURN وجود ندارد. این به دلیل این واقعیت است که سرور TURN از طریق جریان های رسانه ای عبور می کند که می تواند به طور قابل توجهی هم کانال شبکه و هم خود سرور را بارگیری کند. بنابراین، ساده ترین راه برای اتصال به سرورهای TURN این است که خودتان آن را نصب کنید (بدیهی است که به یک IP عمومی نیاز خواهید داشت). از بین همه سرورها به نظر من بهترین سرور rfc5766-turn-server است. حتی یک تصویر آماده برای آمازون EC2 وجود دارد.

با TURN، همه چیز آنطور که ما می خواهیم خوب نیست، اما توسعه فعال در حال انجام است، و من می خواهم امیدوار باشم که پس از مدتی WebRTC، اگر از نظر کیفیت عبور از طریق ترجمه آدرس (NAT) و فایروال ها با Skype برابر نباشد. ، حداقل قابل توجه است نزدیکتر خواهد شد.

RTCMediaConnection به یک مکانیسم اضافی برای تبادل اطلاعات کنترلی برای ایجاد یک اتصال نیاز دارد - اگرچه این داده ها را تولید می کند، اما آن را انتقال نمی دهد و انتقال به سایر شرکت کنندگان باید به طور جداگانه اجرا شود.


انتخاب روش انتقال به توسعه دهنده بستگی دارد - حداقل به صورت دستی. به محض اینکه تبادل داده های لازم انجام شود، RTCMediaConnection به طور خودکار جریان های رسانه ای را نصب می کند (البته در صورت امکان).

مدل پیشنهاد-پاسخ

برای ایجاد و تغییر جریان های رسانه ای، از مدل پیشنهاد/پاسخ (شرح شده در RFC3264) و SDP (پروتکل شرح جلسه) استفاده می شود. آنها همچنین توسط پروتکل SIP استفاده می شوند. در این مدل، دو عامل وجود دارد: Offerer - کسی که توضیحات SDP جلسه را ایجاد می کند تا یک مورد جدید ایجاد کند یا موجودی را اصلاح می کند (Offer SDP) و Answerer - کسی که توضیحات SDP جلسه را از آن دریافت می کند. یک نماینده دیگر و با توضیحات جلسه خود پاسخ می دهد (پاسخ SDP). در عین حال، مشخصات به یک پروتکل سطح بالاتر (به عنوان مثال، SIP یا خود روی سوکت های وب، مانند مورد ما) نیاز دارد که مسئول انتقال SDP بین عوامل است.

چه داده‌هایی باید بین دو RTCMediaConnection ارسال شوند تا بتوانند با موفقیت جریان‌های رسانه‌ای ایجاد کنند:

  • اولین شرکت‌کننده‌ای که اتصال را آغاز می‌کند پیشنهادی را تشکیل می‌دهد که در آن یک ساختار داده SDP را ارسال می‌کند (همان پروتکل برای همان هدف در SIP استفاده می‌شود) که ویژگی‌های احتمالی جریان رسانه‌ای را که قرار است شروع به ارسال کند، توصیف می‌کند. این بلوک داده باید به شرکت کننده دوم منتقل شود. شرکت‌کننده دوم یک پاسخ با SDP خود تشکیل می‌دهد و آن را برای نفر اول ارسال می‌کند.
  • هر دو شرکت‌کننده اول و دوم روند تعیین نامزدهای احتمالی ICE را انجام می‌دهند که با کمک آن شرکت‌کننده دوم می‌تواند جریان رسانه‌ای را به آنها منتقل کند. با شناسایی نامزدها، اطلاعات مربوط به آنها باید به شرکت کننده دیگری منتقل شود.

پیشنهاد تشکیل

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

علاوه بر این، به دو کنترل کننده رویداد نیاز است: onicecandidate هنگام تعریف یک نامزد جدید ICE و onaddstream هنگام اتصال یک جریان رسانه از سمت دور. بیایید به پرونده خود برگردیم. بیایید بعد از خطوط دارای عناصر، یکی دیگر به HTML اضافه کنیم:

ایجاد پیشنهاد

و بعد از خط با عنصر (برای آینده):


همچنین در ابتدای کد جاوا اسکریپت، یک متغیر جهانی برای RTCPeerConnection اعلام می کنیم:

Var pc1;

هنگام فراخوانی سازنده RTCPeerConnection، باید سرورهای STUN/TURN را مشخص کنید. برای اطلاعات بیشتر در مورد آنها، به نوار کناری مراجعه کنید. تا زمانی که همه شرکت کنندگان در یک شبکه باشند، نیازی به آنها نیست.

سرورهای Var = null;

پارامترهای تهیه SDP پیشنهاد

Var offerConstraints = ();

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

تابع pc1_createOffer_success(desc) (consol.log("pc1_createOffer_success(): \ndesc.sdp:\n"+desc.sdp+"desc:", desc); pc1.setLocalDescription(desc)؛ // تنظیم RTCPeerConnection تولید شده با استفاده از متد setLocalDescription. // وقتی سمت دور پاسخ SDP خود را می‌فرستد، باید با استفاده از روش setRemoteDescription تنظیم شود // تا زمانی که طرف دوم پیاده‌سازی نشود، کاری انجام نمی‌دهیم // pc2_receivedOffer(desc); )

پارامتر دوم یک تابع callback است که در صورت بروز خطا فراخوانی می شود

تابع pc1_createOffer_error(error)(consol.log("pc1_createOffer_success_error(): خطا:"، خطا)؛ )

و بیایید یک تابع فراخوانی را اعلام کنیم که نامزدهای ICE همانطور که مشخص شده اند به آن منتقل می شوند:

تابع pc1_onicecandidate(event)( if (event.candidate) (consol.log("pc1_onicecandidate():\n"+ event.candidate.candidate.replace("\r\n", ""), event.candidate); // تا زمانی که طرف دوم اجرا نشود، کاری انجام نمی دهیم // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); ) )

و همچنین یک تابع تماس برای اضافه کردن یک جریان رسانه از سمت دور (برای آینده، زیرا در حال حاضر فقط یک RTCPeerConnection داریم):

تابع pc1_onaddstream(رویداد) (consol.log("pc_onaddstream()"); remoteVideo1.src = URL.createObjectURL(event.stream);)

هنگامی که روی دکمه "createOffer" کلیک می کنید، یک RTCPeerConnection ایجاد می کنیم، متدهای onicecandidate و onaddstream را تنظیم می کنیم و با فراخوانی متد ()createOffer درخواست تشکیل یک Offer SDP را می کنیم:

تابع createOffer_click() (consol.log("createOffer_click()"); pc1 = وب کیت جدیدRTCPeerConnection(سرورها)؛ // ایجاد RTCPeerConnection pc1.onicecandidate = pc1_onicecandidate؛ // تابع Callback برای پردازش pc1.c1. تابع Callback هنگامی که یک جریان رسانه از سمت دور ظاهر می شود، فراخوانی می شود. هنوز هیچ کدام وجود ندارد pc1.addStream(localStream)؛ // بیایید جریان رسانه محلی (با فرض اینکه قبلاً دریافت شده است) را انتقال دهیم pc1.createOffer(// و در واقع درخواست کنیم تشکیل Offer pc1_createOffer_success، pc1_createOffer_error، offerConstraints)؛

بیایید فایل را به عنوان rtctest2.html ذخیره کنیم، آن را در سرور آپلود کنیم، آن را در یک مرورگر باز کنیم و در کنسول ببینیم که در طول عملیات آن چه داده هایی تولید می شود. ویدیوی دوم هنوز ظاهر نمی شود، زیرا فقط یک شرکت کننده وجود دارد. بیایید به یاد بیاوریم که SDP توصیفی از پارامترهای یک جلسه رسانه است، کدک های موجود، جریان های رسانه ای، و نامزدهای ICE گزینه های ممکن برای اتصال به یک شرکت کننده مشخص هستند.

تشکیل پاسخ SDP و تبادل نامزدهای ICE

هم Offer SDP و هم هر یک از نامزدهای ICE باید به طرف دیگر منتقل شوند و در آنجا، پس از دریافت آنها، RTCPeerConnection متدهای setRemoteDescription را برای Offer SDP و addIceCandidate را برای هر کاندیدای ICE دریافت شده از طرف دور فراخوانی می کند. به طور مشابه در سمت معکوسبرای پاسخ به نامزدهای SDP و ICE از راه دور. پاسخ SDP خود مشابه Offer شکل گرفته است. تفاوت این است که متد createOffer فراخوانی نمی شود، بلکه متد createAnswer است و قبل از آن متد RTCPeerConnection setRemoteDescription به Offer SDP دریافت شده از تماس گیرنده ارسال می شود.

بیایید یک عنصر ویدیویی دیگر به HTML اضافه کنیم:

و یک متغیر سراسری برای دومین RTCPeerConnection تحت اعلان مورد اول:

Var pc2;

پردازش پیشنهاد و پاسخ SDP

شکل گیری Answer SDP بسیار شبیه Offer است. در تابع فراخوانی که پس از تشکیل موفقیت آمیز یک پاسخ، مشابه Offer نامیده می شود، یک توصیف محلی ارائه می دهیم و SDP پاسخ دریافتی را به اولین شرکت کننده ارسال می کنیم:

تابع pc2_createAnswer_success(desc) (pc2.setLocalDescription(desc); console.log("pc2_createAnswer_success()"، desc.sdp); pc1.setRemoteDescription(desc); )

تابع callback که در صورت بروز خطا در هنگام ایجاد پاسخ فراخوانی می شود، کاملاً شبیه Offer است:

تابع pc2_createAnswer_error(خطا) (consol.log("pc2_createAnswer_error():"، خطا)؛ )

پارامترهای تشکیل Answer SDP:

Var answerConstraints = ( "اجباری": ( "OfferToReceiveAudio":true, "OfferToReceiveVideo":true ) );

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

تابع pc2_receivedOffer(desc) ( console.log("pc2_receiveOffer()"، desc); // یک شی RTCPeerConnection برای شرکت کننده دوم به همان روشی که اولین شرکت کننده ایجاد می کند pc2 = new webkitRTCPeerConnection(servers)؛ pc2.ondidate2. ؛ // تنظیم کننده رویداد زمانی که کاندید ICE ظاهر شد pc2.onaddstream = pc_onaddstream؛ // هنگامی که یک جریان ظاهر شد، آن را به HTML pc2.addStream(localStream) وصل کنید؛ // جریان رسانه محلی را منتقل کنید (در مثال ما، دوم شرکت کننده همان مورد اول را دارد) // حالا، وقتی RTCPeerConnection دوم آماده شد، Offer SDP دریافت شده را به آن منتقل می کنیم (ما جریان محلی را به اولین مورد ارسال کردیم) pc2.setRemoteDescription(new RTCSessionDescription(desc)); // درخواست اتصال دوم برای تولید داده برای پیام پاسخ pc2.createAnswer (pc2_createAnswer_success, pc2_createAnswer_error, answerConstraints); )

برای انتقال SDP از اولین شرکت کننده به شرکت کننده دوم در مثال ما، اجازه دهید آن را در تابع pc1 از نظر خارج کنیم. ایجاد پیشنهادخط تماس موفقیت():

PC2_receivedOffer(desc);

برای پیاده سازی پردازش نامزدهای ICE، اجازه دهید در کنترل کننده رویداد آمادگی نامزد ICE اولین شرکت کننده pc1_onicecandidate() انتقال آن را به دومین شرکت کننده حذف کنیم:

Pc2.addIceCandidate(new RTCIceCandidate(event.candidate));

کنترل کننده رویداد آمادگی کاندیدای ICE شرکت‌کننده دوم مانند آینه اول است:

تابع pc2_onicecandidate(event) ( if (event.candidate) ( console.log("pc2_onicecandidate():"، event.candidate.candidate); pc1.addIceCandidate(new RTCIceCandidate(event.candidate)); ))

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

تابع pc2_onaddstream(رویداد) (consol.log("pc_onaddstream()"); remoteVideo2.src = URL.createObjectURL(event.stream);)

پایان دادن به اتصال

بیایید یک دکمه دیگر به HTML اضافه کنیم

قطع کن

و یک تابع برای پایان دادن به اتصال

تابع btnHangupClick() (// قطع ارتباط ویدیوی محلی از عناصر HTML، توقف جریان رسانه محلی، تنظیم = null localVideo1.src = ""؛ localStream.stop(); localStream = null؛ // برای هر شرکت کننده، ویدیو را از HTML غیرفعال کنید عناصر، اتصال را ببندید، نشانگر را تنظیم کنید = null remoteVideo1.src = ""؛ pc1.close(); pc1 = null؛ remoteVideo2.src = ""؛ pc2.close(); pc2 = null; )

بیایید آن را به عنوان rtctest3.html ذخیره کنیم، آن را در سرور آپلود کرده و در مرورگر باز کنیم. این مثال انتقال دو طرفه جریان های رسانه ای را بین دو RTCPeerConnection در یک برگه مرورگر پیاده سازی می کند. برای سازماندهی تبادل پیشنهاد و پاسخ SDP، نامزدهای ICE بین شرکت کنندگان و سایر اطلاعات از طریق شبکه، به جای تماس مستقیم رویه ها، لازم است مبادله بین شرکت کنندگان با استفاده از نوعی حمل و نقل، در مورد ما - سوکت های وب، اجرا شود.

پخش روی صفحه نمایش

تابع getUserMedia همچنین می‌تواند با تعیین پارامترهای زیر از صفحه نمایش و پخش جریانی به عنوان MediaStream استفاده کند:

Var mediaStreamConstraints = ( صدا: نادرست، ویدیو: (اجباری: ( chromeMediaSource: "صفحه")، اختیاری: ) );

برای دسترسی موفقیت آمیز به صفحه، چند شرط باید رعایت شود:

  • فعال کردن پرچم اسکرین شات در getUserMedia() در chrome://flags/,chrome://flags/;
  • فایل منبع باید از طریق HTTPS (منبع SSL) دانلود شود.
  • جریان صوتی نباید درخواست شود.
  • چندین درخواست نباید در یک برگه مرورگر اجرا شوند.
کتابخانه ها برای WebRTC

اگرچه WebRTC هنوز تکمیل نشده است، چندین کتابخانه بر اساس آن قبلاً ظاهر شده اند. JsSIP برای ایجاد تلفن های نرم افزاری مبتنی بر مرورگر طراحی شده است که با سوئیچ های SIP مانند Asterisk و Camalio کار می کنند. PeerJS ایجاد شبکه های P2P را برای تبادل داده آسان تر می کند و Holla میزان توسعه مورد نیاز برای ارتباطات P2P از مرورگرها را کاهش می دهد.

Node.js و socket.io

برای سازماندهی تبادل SDP و ICE نامزد بین دو RTCPeerConnection از طریق شبکه، از Node.js با ماژول socket.io استفاده می کنیم.

نصب آخرین نسخه پایدار Node.js (برای Debian/Ubuntu) توضیح داده شده است

$ sudo apt-get نصب python-software-properties python g++ make $ sudo add-apt-repository ppa:chris-lea/node.js $ sudo apt-get update $ sudo apt-get install nodejs

نصب برای دیگران سیستم عاملشرح داده شده

بیایید بررسی کنیم:

$ echo "sys=require("util"); sys.puts("Test message");" > nodetest1.js $ nodejs nodetest1.js

با استفاده از npm (Node Package Manager) socket.io و ماژول اکسپرس اضافی را نصب خواهیم کرد:

$ npm نصب socket.io express

بیایید آن را با ایجاد یک فایل nodetest2.js برای سمت سرور آزمایش کنیم:

$ nano nodetest2.js var app = require("express")() , server = require("http").createServer(app) , io = require("socket.io").listen(server); server.listen(80); // اگر پورت 80 رایگان است app.get("/"، تابع (req، res) ( // هنگام دسترسی به صفحه اصلی res.sendfile(__dirname + "/nodetest2.html"); // فایل HTML را ارسال کنید) ) ؛ io.sockets.on("اتصال"، تابع (سوکت) ( // هنگام اتصال socket.emit("رویداد سرور"، ( hello: "world")); // یک پیام ارسال کنید socket.on("رویداد مشتری" , تابع (داده) ( // و زمانی که پیامی از کلاینت console.log(data); )) می رسد یک کنترل کننده رویداد را اعلام می کند.

و nodetest2.html برای سمت کلاینت:

$ nano nodetest2.html var socket = io.connect("/"); // URL سرور Websocket (صفحه اصلی سروری که صفحه از آن بارگیری شده است) socket.on("رویداد سرور"، تابع (داده) (consol.log(data); socket.emit("رویداد مشتری"، ( "نام": "ارزش" ))));

بیایید سرور را راه اندازی کنیم:

$ sudo nodejs nodetest2.js

و صفحه http://localhost:80 (اگر به صورت محلی در پورت 80 اجرا می شود) را در مرورگر باز کنید. اگر همه چیز موفقیت آمیز باشد، در کنسول جاوا اسکریپت مرورگر شاهد تبادل رویدادها بین مرورگر و سرور در هنگام اتصال خواهیم بود.

تبادل اطلاعات بین RTCPeerConnection از طریق سوکت های وب بخش Client

بیایید مثال اصلی خود (rtcdemo3.html) را با نام جدید rtcdemo4.html ذخیره کنیم. بیایید کتابخانه socket.io را در عنصر قرار دهیم:

و در ابتدای اسکریپت جاوا اسکریپت - اتصال به وب سوکت ها:

سوکت Var = io.connect("http://localhost");

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

تابع createOffer_success(desc) ( ... // pc2_receivedOffer(desc); socket.emit("پیشنهاد"، توصیف)؛ ... ) تابع pc2_createAnswer_success(desc) (... // pc1.setRemoteDescription(desc); سوکت .emit("answer"، desc); ) function pc1_onicecandidate(event) (... // pc2.addIceCandidate(new RTCIceCandidate(event.candidate)); socket.emit("ice1"، event.candidate)؛ .. ).

در تابع hangup() به جای فراخوانی مستقیم توابع شرکت‌کننده دوم، پیامی را از طریق سوکت‌های وب ارسال می‌کنیم:

تابع btnHangupClick(... // remoteVideo2.src = ""; pc2.close(); pc2 = null; socket.emit("hangup"، ())؛ )

و کنترل کننده های دریافت پیام را اضافه کنید:

Socket.on("پیشنهاد"، تابع (داده) ( console.log("socket.on("پیشنهاد"):"، داده); pc2_receivedOffer(داده); )); socket.on("پاسخ"، تابع (داده) (е console.log("socket.on("پاسخ"):"، داده)؛ pc1.setRemoteDescription(new RTCSessionDescription(داده)); )); socket.on("ice1"، تابع (داده) ( console.log("socket.on("ice1"):" data); pc2.addIceCandidate(new RTCIceCandidate(داده)); )); socket.on("ice2"، تابع (داده) ( console.log("socket.on("ice2"):" data); pc1.addIceCandidate(new RTCIceCandidate(data)); )); socket.on("hangup"، تابع (داده) ( console.log("socket.on("hangup"):"، data); remoteVideo2.src = ""; pc2.close(); pc2 = null; ) )

بخش سرور

در سمت سرور، فایل nodetest2 را با نام جدید rtctest4.js ذخیره کنید و در داخل تابع io.sockets.on("connection", function (socket) (...) دریافت و ارسال پیام های مشتری را اضافه خواهیم کرد:

Socket.on("offer", function (data) ( // وقتی پیام "offer" را دریافت می کنیم، // از آنجایی که در این مثال فقط یک اتصال مشتری وجود دارد، // پیام را از طریق همان سوکت سوکت ارسال می کنیم. .emit("پیشنهاد" , داده); // اگر لازم بود پیام از طریق همه اتصالات فوروارد شود، // به جز فرستنده: // soket.broadcast.emit("پیشنهاد"، داده); )); socket.on("پاسخ"، تابع (داده) ( socket.emit("پاسخ"، داده); )); socket.on("ice1"، تابع (داده) ( socket.emit("ice1", data); )); socket.on("ice2"، تابع (داده) ( socket.emit("ice2", data); )); socket.on("Hangup"، تابع (داده) ( socket.emit("Hangup", data); ));

علاوه بر این، اجازه دهید نام فایل HTML را تغییر دهیم:

// res.sendfile(__dirname + "/nodetest2.html"); // ارسال فایل HTML res.sendfile(__dirname + "/rtctest4.html");

راه اندازی سرور:

$ sudo nodejs nodetest2.js

علیرغم این واقعیت که کد هر دو مشتری در یک برگه مرورگر اجرا می شود، تمام تعاملات بین شرکت کنندگان در مثال ما به طور کامل از طریق شبکه انجام می شود و "جدا کردن" شرکت کنندگان به هیچ مشکل خاصی نیاز ندارد. با این حال، کاری که ما انجام دادیم نیز بسیار ساده بود - این فناوری ها خوب هستند زیرا استفاده از آنها آسان است. حتی اگر گاهی فریبنده باشد. به طور خاص، بیایید فراموش نکنیم که بدون سرورهای STUN/TURN نمونه ما در حضور ترجمه آدرس و فایروال‌ها نمی‌تواند کار کند.

نتیجه

مثال به دست آمده بسیار معمولی است، اما اگر کنترل کننده های رویداد را کمی جهانی کنیم تا بین تماس گیرنده و طرف تماس گیرنده تفاوتی نداشته باشند، به جای دو شی pc1 و pc2، یک آرایه RTCPeerConnection بسازید و پیاده سازی کنید. ایجاد پویاو با حذف عناصر، یک چت ویدیویی کاملا قابل استفاده دریافت خواهید کرد. هیچ ویژگی خاصی در ارتباط با WebRTC وجود ندارد و نمونه‌ای از یک چت ویدیویی ساده برای چندین شرکت‌کننده (و همچنین متون تمام نمونه‌های مقاله) روی دیسک همراه مجله موجود است. با این حال، شما در حال حاضر می توانید در اینترنت چیزهای زیادی پیدا کنید. نمونه های خوب. به ویژه، در تهیه مقاله از موارد زیر استفاده شد: simpl.info getUserMedia، simpl.info RTCPeerConnection، WebRTC Reference App.

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




بالا