WebRTC یک جبهه جدید در جنگ طولانی برای یک وب باز و بدون محدودیت است.
برندان آیش، مخترع جاوا اسکریپت
ارتباط بلادرنگ بدون پلاگین
دنیایی را تصور کنید که در آن تلفن، تلویزیون و رایانه شما می توانند بر روی یک پلت فرم مشترک با هم ارتباط برقرار کنند. تصور کنید اضافه کردن چت ویدیویی و اشتراکگذاری دادههای همتا به همتا به برنامه وبتان آسان است. این چشم انداز WebRTC است.
می خواهید آن را امتحان کنید؟ WebRTC روی دسکتاپ و موبایل در گوگل کروم، سافاری، فایرفاکس و اپرا در دسترس است. یک مکان خوب برای شروع، برنامه چت ویدیویی ساده در appr.tc است:
- appr.tc را در مرورگر خود باز کنید.
- روی Join کلیک کنید تا به اتاق چت بپیوندید و به برنامه اجازه دهید از وب کم شما استفاده کند.
- URL نمایش داده شده در انتهای صفحه را در یک برگه جدید یا بهتر است در رایانه دیگری باز کنید.
شروع سریع
آیا برای خواندن این مقاله وقت ندارید یا فقط کد می خواهید؟
- برای دریافت نمای کلی از WebRTC، ویدیوی Google I/O زیر را تماشا کنید یا این اسلایدها را مشاهده کنید:
- اگر از
getUserMedia
API استفاده نکردهاید، به ضبط صدا و ویدیو در HTML5 و simpl.info getUserMedia مراجعه کنید. - برای آشنایی با
RTCPeerConnection
API، به مثال زیر و «simpl.info RTCPeerConnection» مراجعه کنید. - برای آشنایی با نحوه استفاده WebRTC از سرورها برای سیگنال دهی، و فایروال و پیمایش NAT، به گزارش کد و کنسول از appr.tc مراجعه کنید.
- نمی توانید صبر کنید و فقط می خواهید WebRTC را در حال حاضر امتحان کنید؟ برخی از بیش از 20 نسخه نمایشی را که از WebRTC JavaScript API استفاده می کنند، امتحان کنید.
- آیا با دستگاه و WebRTC خود مشکل دارید؟ از عیب یاب WebRTC دیدن کنید.
از طرف دیگر، مستقیماً به کد WebRTC بروید، یک راهنمای گام به گام که نحوه ساخت یک برنامه چت ویدیویی کامل، از جمله یک سرور سیگنالینگ ساده را توضیح میدهد.
تاریخچه بسیار کوتاه WebRTC
یکی از آخرین چالشهای اصلی برای وب، فعال کردن ارتباط انسانی از طریق صدا و تصویر است: ارتباطات بلادرنگ یا به اختصار RTC. RTC باید در یک برنامه وب به اندازه وارد کردن متن در ورودی متن طبیعی باشد. بدون آن، شما در توانایی خود برای نوآوری و ایجاد راه های جدید برای تعامل افراد محدود هستید.
از لحاظ تاریخی، RTC شرکتی و پیچیده بوده است و نیاز به فناوریهای گران قیمت صوتی و تصویری برای مجوز یا توسعه داخلی دارد. ادغام فناوری RTC با محتوا، داده ها و خدمات موجود، به ویژه در وب، دشوار و وقت گیر بوده است.
چت تصویری جیمیل در سال 2008 رایج شد و در سال 2011، گوگل Hangouts را معرفی کرد که از Talk (همانند جیمیل) استفاده می کند. گوگل GIPS را خریداری کرد، شرکتی که بسیاری از مؤلفههای مورد نیاز برای RTC، مانند کدکها و تکنیکهای لغو اکو را توسعه داد. Google فناوریهای توسعهیافته توسط GIPS را منبع باز کرد و با نهادهای استاندارد مربوطه در گروه ضربت مهندسی اینترنت (IETF) و کنسرسیوم وب جهانی (W3C) برای اطمینان از اجماع صنعت درگیر شد. در می 2011، اریکسون اولین پیاده سازی WebRTC را ساخت.
WebRTC استانداردهای باز را برای ارتباط ویدیویی، صوتی و داده ای بدون پلاگین در زمان واقعی پیاده سازی کرد. نیاز واقعی بود:
- بسیاری از سرویس های وب از RTC استفاده می کردند، اما به دانلود، برنامه های بومی یا افزونه نیاز داشتند. اینها شامل اسکایپ، فیس بوک و Hangouts بودند.
- دانلود، نصب و بهروزرسانی افزونهها پیچیده، مستعد خطا و آزاردهنده است.
- استقرار، اشکال زدایی، عیب یابی، آزمایش و نگهداری پلاگین ها دشوار است - و ممکن است نیاز به مجوز و ادغام با فناوری پیچیده و گران قیمت داشته باشند. اغلب متقاعد کردن افراد برای نصب افزونه ها در وهله اول دشوار است!
اصول راهنمای پروژه WebRTC این است که APIهای آن باید منبع باز، رایگان، استاندارد، ساخته شده در مرورگرهای وب و کارآمدتر از فناوری های موجود باشند.
الان کجا هستیم؟
WebRTC در برنامه های مختلفی مانند Google Meet استفاده می شود. WebRTC همچنین با برنامه های اصلی WebKitGTK و Qt یکپارچه شده است.
WebRTC این سه API را پیاده سازی می کند: - MediaStream
(همچنین به عنوان getUserMedia
شناخته می شود) - RTCPeerConnection
- RTCDataChannel
API ها در این دو مشخصات تعریف شده اند:
هر سه API در موبایل و دسکتاپ توسط کروم، سافاری، فایرفاکس، اج و اپرا پشتیبانی میشوند.
getUserMedia
: برای دمو و کد، نمونههای WebRTC را ببینید یا نمونههای شگفتانگیز کریس ویلسون را امتحان کنید که از getUserMedia
به عنوان ورودی برای صدای وب استفاده میکند.
RTCPeerConnection
: برای یک نسخه آزمایشی ساده و یک برنامه چت ویدیویی کاملاً کاربردی، به ترتیب به نمونههای WebRTC اتصال همتا و appr.tc مراجعه کنید. این برنامه از adapter.js ، یک شیم جاوا اسکریپت که توسط Google با کمک انجمن WebRTC نگهداری میشود، استفاده میکند تا تفاوتهای مرورگر و تغییرات مشخصات را از بین ببرد.
RTCDataChannel
: برای مشاهده این در عمل، نمونههای WebRTC را ببینید تا یکی از دموهای کانال داده را بررسی کنید.
نرم افزار WebRTC نشان می دهد که چگونه می توان از هر سه API برای ساخت یک برنامه ساده برای چت ویدیویی و اشتراک گذاری فایل استفاده کرد.
اولین WebRTC شما
برنامه های WebRTC باید چندین کار را انجام دهند:
- پخش جریانی صدا، ویدیو یا دادههای دیگر را دریافت کنید.
- اطلاعات شبکه مانند آدرسهای IP و پورتها را دریافت کنید و آنها را با سایر مشتریان WebRTC (معروف به همتایان ) مبادله کنید تا اتصال را حتی از طریق NAT و فایروالها فعال کنید.
- ارتباطات سیگنالینگ را برای گزارش خطاها و شروع یا بستن جلسات هماهنگ کنید.
- تبادل اطلاعات در مورد رسانه و قابلیت مشتری، مانند وضوح و کدک.
- پخش جریانی صدا، ویدئو یا داده را برقرار کنید.
برای به دست آوردن و برقراری ارتباط داده های جریانی، WebRTC API های زیر را پیاده سازی می کند:
-
MediaStream
به جریان های داده مانند دوربین و میکروفون کاربر دسترسی پیدا می کند. -
RTCPeerConnection
تماس صوتی یا تصویری را با امکاناتی برای رمزگذاری و مدیریت پهنای باند فعال می کند. -
RTCDataChannel
ارتباط همتا به همتای داده های عمومی را امکان پذیر می کند.
(بعداً بحث مفصلی در مورد جنبه های شبکه و سیگنالینگ WebRTC وجود دارد.)
MediaStream
API (همچنین به عنوان getUserMedia
API شناخته می شود)
MediaStream
API جریان های همگام سازی شده رسانه را نشان می دهد. برای مثال، جریانی که از ورودی دوربین و میکروفون گرفته شده است، آهنگهای ویدیویی و صوتی را همگامسازی میکند. ( MediaStreamTrack
با عنصر <track>
اشتباه نگیرید، که چیزی کاملاً متفاوت است.)
احتمالاً سادهترین راه برای درک MediaStream
API این است که به آن نگاه کنید:
- در مرورگر خود، به نمونه WebRTC
getUserMedia
بروید. - کنسول را باز کنید.
- متغیر
stream
را که در محدوده جهانی است بررسی کنید.
هر MediaStream
یک ورودی دارد که ممکن است یک MediaStream
تولید شده توسط getUserMedia()
و یک خروجی باشد که ممکن است به یک عنصر ویدیویی یا یک RTCPeerConnection
ارسال شود.
متد getUserMedia()
یک پارامتر شی MediaStreamConstraints
را می گیرد و یک Promise
برمی گرداند که به یک شی MediaStream
حل می شود.
هر MediaStream
دارای یک label
است، مانند 'Xk7EuLhsuHKbnjLWkW4yYGNJJ8ONsgwHBvLQ'
. آرایه ای از MediaStreamTrack
s توسط متدهای getAudioTracks()
و getVideoTracks()
برگردانده می شود.
برای مثال getUserMedia
، stream.getAudioTracks()
یک آرایه خالی را برمی گرداند (زیرا صدا وجود ندارد) و با فرض اینکه یک وب کم کار متصل است، stream.getVideoTracks()
آرایه ای از یک MediaStreamTrack
را برمی گرداند که نشان دهنده جریان از وب کم است. هر MediaStreamTrack
دارای یک نوع ( 'video'
یا 'audio'
)، یک label
(چیزی شبیه 'FaceTime HD Camera (Built-in)'
) است و یک یا چند کانال صوتی یا تصویری را نشان میدهد. در این مورد، تنها یک آهنگ ویدیویی وجود دارد و صدا وجود ندارد، اما به راحتی می توان موارد استفاده را تصور کرد که موارد بیشتری وجود دارد، مانند یک برنامه چت که جریان را از دوربین جلو، دوربین عقب، میکروفون، و برنامه ای که آن را به اشتراک می گذارد، دریافت می کند. صفحه نمایش
یک MediaStream
می توان با تنظیم ویژگی srcObject
به یک عنصر ویدیویی متصل کرد. قبلاً، این کار با تنظیم ویژگی src
روی یک URL شی ایجاد شده با URL.createObjectURL()
انجام می شد، اما این مورد منسوخ شده است .
getUserMedia
همچنین می تواند به عنوان یک گره ورودی برای Web Audio API استفاده شود:
// Cope with browser differences.
let audioContext;
if (typeof AudioContext === 'function') {
audioContext = new AudioContext();
} else if (typeof webkitAudioContext === 'function') {
audioContext = new webkitAudioContext(); // eslint-disable-line new-cap
} else {
console.log('Sorry! Web Audio not supported.');
}
// Create a filter node.
var filterNode = audioContext.createBiquadFilter();
// See https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#BiquadFilterNode-section
filterNode.type = 'highpass';
// Cutoff frequency. For highpass, audio is attenuated below this frequency.
filterNode.frequency.value = 10000;
// Create a gain node to change audio volume.
var gainNode = audioContext.createGain();
// Default is 1 (no change). Less than 1 means audio is attenuated
// and vice versa.
gainNode.gain.value = 0.5;
navigator.mediaDevices.getUserMedia({audio: true}, (stream) => {
// Create an AudioNode from the stream.
const mediaStreamSource =
audioContext.createMediaStreamSource(stream);
mediaStreamSource.connect(filterNode);
filterNode.connect(gainNode);
// Connect the gain node to the destination. For example, play the sound.
gainNode.connect(audioContext.destination);
});
برنامهها و برنامههای افزودنی مبتنی بر کروم نیز میتوانند getUserMedia
در خود جای دهند. افزودن مجوزهای audioCapture
و/یا videoCapture
به مانیفست این اجازه را میدهد که تنها یک بار پس از نصب درخواست و اعطا شود. پس از آن، از کاربر برای دسترسی به دوربین یا میکروفون درخواست اجازه نمیشود.
مجوز فقط باید یک بار برای getUserMedia()
اعطا شود. برای اولین بار، یک دکمه Allow در نوار اطلاعات مرورگر نمایش داده می شود. دسترسی HTTP برای getUserMedia()
در پایان سال 2015 توسط کروم منسوخ شد زیرا به عنوان یک ویژگی قدرتمند طبقه بندی شده بود.
هدف به طور بالقوه فعال کردن MediaStream
برای هر منبع داده جریانی است، نه تنها یک دوربین یا میکروفون. این امکان پخش جریانی از داده های ذخیره شده یا منابع داده دلخواه، مانند حسگرها یا ورودی های دیگر را فراهم می کند.
getUserMedia()
واقعاً در ترکیب با سایر APIها و کتابخانه های جاوا اسکریپت زنده می شود:
- Webcam Toy یک برنامه Photobooth است که از WebGL برای اضافه کردن جلوه های عجیب و غریب و شگفت انگیز به عکس هایی که می توانند به صورت محلی به اشتراک گذاشته یا ذخیره شوند، استفاده می کند.
- FaceKat یک بازی ردیابی چهره است که با headtrackr.js ساخته شده است.
- دوربین ASCII از Canvas API برای تولید تصاویر ASCII استفاده می کند.
محدودیت ها
محدودیتها میتوانند برای تنظیم مقادیر وضوح ویدیو برای getUserMedia()
استفاده شوند. این همچنین امکان پشتیبانی از محدودیت های دیگر مانند نسبت ابعاد را فراهم می کند. حالت روبرو (دوربین جلو یا عقب)؛ نرخ فریم، ارتفاع و عرض؛ و یک متد applyConstraints()
.
برای مثال، نمونههای WebRTC را ببینید getUserMedia
: رزولوشن را انتخاب کنید .
تنظیم یک مقدار محدودیت غیرمجاز یک DOMException
یا یک OverconstrainedError
می دهد اگر، برای مثال، وضوح درخواستی در دسترس نباشد. برای مشاهده عملکرد، به نمونههای WebRTC مراجعه کنید getUserMedia
: رزولوشن را برای یک نسخه نمایشی انتخاب کنید .
ضبط صفحه و برگه
برنامههای Chrome همچنین اشتراکگذاری یک ویدیوی زنده از یک برگه مرورگر یا کل دسکتاپ را از طریق chrome.tabCapture
و chrome.desktopCapture
ممکن میسازند. (برای یک نسخه آزمایشی و اطلاعات بیشتر، به اشتراک گذاری صفحه با WebRTC مراجعه کنید. مقاله چند سال پیش است، اما هنوز هم جالب است.)
همچنین میتوان با استفاده از محدودیت آزمایشی chromeMediaSource
از تصویربرداری از صفحه بهعنوان منبع MediaStream
در Chrome استفاده کرد. توجه داشته باشید که ضبط صفحه نیاز به HTTPS دارد و باید فقط برای توسعه استفاده شود زیرا از طریق یک پرچم خط فرمان همانطور که در این پست توضیح داده شده است فعال است.
سیگنالینگ: اطلاعات کنترل جلسه، شبکه و رسانه
WebRTC از RTCPeerConnection
برای برقراری ارتباط جریان داده بین مرورگرها (همچنین به عنوان همتایان) استفاده می کند، اما همچنین به مکانیزمی برای هماهنگ کردن ارتباطات و ارسال پیام های کنترلی نیاز دارد، فرآیندی که به عنوان سیگنالینگ شناخته می شود. روش ها و پروتکل های سیگنالینگ توسط WebRTC مشخص نشده اند. سیگنالینگ بخشی از RTCPeerConnection
API نیست.
در عوض، توسعه دهندگان برنامه WebRTC می توانند هر پروتکل پیام رسانی را که ترجیح می دهند، مانند SIP یا XMPP و هر کانال ارتباطی دوطرفه (دو طرفه) مناسب را انتخاب کنند. مثال appr.tc از XHR و Channel API به عنوان مکانیزم سیگنالینگ استفاده می کند. Codelab از Socket.io در حال اجرا بر روی سرور Node استفاده می کند.
سیگنالینگ برای تبادل سه نوع اطلاعات استفاده می شود:
- پیام های کنترل جلسه: برای تنظیم اولیه یا بستن ارتباطات و گزارش خطاها.
- پیکربندی شبکه: به دنیای خارج، آدرس IP و پورت رایانه شما چیست؟
- قابلیتهای رسانه: مرورگر شما و مرورگری که میخواهد با آن ارتباط برقرار کند، چه کدکها و وضوحهایی را میتواند مدیریت کند؟
مبادله اطلاعات از طریق سیگنالینگ باید قبل از شروع پخش همتا به همتا با موفقیت انجام شده باشد.
به عنوان مثال، تصور کنید آلیس می خواهد با باب ارتباط برقرار کند. در اینجا یک نمونه کد از مشخصات W3C WebRTC است که فرآیند سیگنال دهی را در عمل نشان می دهد. این کد وجود مکانیزم سیگنال دهی ایجاد شده در متد createSignalingChannel()
را فرض می کند. همچنین توجه داشته باشید که در کروم و اپرا، RTCPeerConnection
در حال حاضر پیشوند دارد.
// handles JSON.stringify/parse
const signaling = new SignalingChannel();
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// Send any ice candidates to the other peer.
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// Let the "negotiationneeded" event trigger offer generation.
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription(await pc.createOffer());
// Send the offer to the other peer.
signaling.send({desc: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// Once remote track media arrives, show it in remote video element.
pc.ontrack = (event) => {
// Don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = event.streams[0];
};
// Call start() to initiate.
async function start() {
try {
// Get local stream, show it in self-view, and add it to be sent.
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({desc, candidate}) => {
try {
if (desc) {
// If you get an offer, you need to reply with an answer.
if (desc.type === 'offer') {
await pc.setRemoteDescription(desc);
const stream =
await navigator.mediaDevices.getUserMedia(constraints);
stream.getTracks().forEach((track) =>
pc.addTrack(track, stream));
await pc.setLocalDescription(await pc.createAnswer());
signaling.send({desc: pc.localDescription});
} else if (desc.type === 'answer') {
await pc.setRemoteDescription(desc);
} else {
console.log('Unsupported SDP type.');
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
ابتدا آلیس و باب اطلاعات شبکه را تبادل می کنند. (عبارت یافتن نامزدها به فرآیند یافتن رابطها و پورتهای شبکه با استفاده از چارچوب ICE اشاره دارد.)
- Alice یک شی
RTCPeerConnection
با یک کنترل کنندهonicecandidate
ایجاد می کند، که زمانی که نامزدهای شبکه در دسترس قرار می گیرند اجرا می شود. - آلیس دادههای نامزد سریالشده را از طریق هر کانال سیگنالی که استفاده میکنند، مانند WebSocket یا مکانیسم دیگری، به باب میفرستد.
- هنگامی که باب یک پیام نامزد از آلیس دریافت می کند،
addIceCandidate
تماس می گیرد تا نامزد را به توضیحات همتا از راه دور اضافه کند.
کلاینتهای WebRTC (که در این مثال بهعنوان همتا یا Alice and Bob نیز شناخته میشوند) همچنین باید اطلاعات رسانههای صوتی و تصویری محلی و از راه دور مانند قابلیتهای وضوح و کدک را شناسایی و تبادل کنند. سیگنال دهی برای تبادل اطلاعات پیکربندی رسانه با تبادل یک پیشنهاد و یک پاسخ با استفاده از پروتکل شرح جلسه (SDP) انجام می شود:
- آلیس متد
createOffer()
RTCPeerConnection
را اجرا می کند. بازگشت از این یکRTCSessionDescription
- شرح جلسه محلی آلیس ارسال می شود. - در تماس برگشتی، آلیس توضیحات محلی را با استفاده از
setLocalDescription()
تنظیم می کند و سپس این توضیحات جلسه را از طریق کانال سیگنالینگ آنها برای Bob ارسال می کند. توجه داشته باشید که تا زمانی کهsetLocalDescription()
فراخوانی نشود،RTCPeerConnection
جمع آوری نامزدها را شروع نمی کند. این در پیش نویس JSEP IETF کدگذاری شده است. - باب توصیفی را که آلیس برای او فرستاده بود با استفاده از
setRemoteDescription()
به عنوان توضیحات راه دور تنظیم می کند. - Bob متد
RTCPeerConnection
createAnswer()
را اجرا میکند و توضیحات راه دوری که از آلیس دریافت کرده است را به آن میفرستد تا بتوان یک جلسه محلی که با جلسه او سازگار است ایجاد کرد. فراخوانیcreateAnswer()
به یکRTCSessionDescription
ارسال می شود. باب آن را به عنوان توضیحات محلی تنظیم می کند و برای آلیس می فرستد. - وقتی آلیس شرح جلسه باب را دریافت می کند، آن را به عنوان توضیحات راه دور با
setRemoteDescription
تنظیم می کند. - پینگ کن
اشیاء RTCSessionDescription
حباب هایی هستند که با پروتکل شرح جلسه ، SDP مطابقت دارند. به صورت سریالی، یک شی SDP به شکل زیر است:
v=0
o=- 3883943731 1 IN IP4 127.0.0.1
s=
t=0 0
a=group:BUNDLE audio video
m=audio 1 RTP/SAVPF 103 104 0 8 106 105 13 126
// ...
a=ssrc:2223794119 label:H4fjnMzxy3dPIgQ7HxuCTLb4wLLLeRHnFxh810
کسب و تبادل اطلاعات شبکه و رسانه می تواند به طور همزمان انجام شود، اما هر دو فرآیند باید قبل از شروع پخش صوتی و تصویری بین همتایان تکمیل شده باشند.
معماری پیشنهاد/پاسخی که قبلا توضیح داده شد، پروتکل استقرار جلسه جاوا اسکریپت یا JSEP نامیده می شود. (یک انیمیشن عالی وجود دارد که فرآیند سیگنال دهی و پخش جریانی را در ویدیوی آزمایشی اریکسون برای اولین اجرای WebRTC توضیح می دهد.)
هنگامی که فرآیند سیگنال دهی با موفقیت به پایان رسید، داده ها می توانند مستقیماً به صورت همتا به همتا، بین تماس گیرنده و تماس گیرنده - یا در صورت عدم موفقیت، از طریق یک سرور رله واسطه (در ادامه در مورد آن بیشتر) پخش شوند. استریم وظیفه RTCPeerConnection
است.
اتصال RTCPeer
RTCPeerConnection
جزء WebRTC است که ارتباط پایدار و کارآمد جریان داده بین همتایان را مدیریت می کند.
شکل زیر یک نمودار معماری WebRTC است که نقش RTCPeerConnection
را نشان می دهد. همانطور که متوجه خواهید شد، قسمت های سبز پیچیده هستند!
از منظر جاوا اسکریپت، اصلیترین چیزی که از این نمودار میتوان فهمید این است که RTCPeerConnection
از توسعهدهندگان وب در برابر پیچیدگیهای بیشمار موجود در زیر آن محافظت میکند. کدکها و پروتکلهای مورد استفاده WebRTC کارهای زیادی را انجام میدهند تا ارتباطات بلادرنگ را حتی از طریق شبکههای غیرقابل اعتماد ممکن کنند:
- پنهان سازی بسته های از دست دادن
- لغو اکو
- سازگاری با پهنای باند
- بافر لرزش پویا
- کنترل بهره خودکار
- کاهش و سرکوب صدا
- پاکسازی تصویر
کد W3C قبلی یک مثال ساده از WebRTC را از منظر سیگنالینگ نشان می دهد. موارد زیر شرحی از دو برنامه کاربردی WebRTC هستند. اولی یک مثال ساده برای نشان دادن RTCPeerConnection
و دومی یک کلاینت چت ویدیویی کاملاً عملیاتی است.
RTCPeerConnection بدون سرور
کد زیر از نمونههای WebRTC پیوند همتا گرفته شده است که دارای RTCPeerConnection
محلی و راه دور (و ویدیوی محلی و راه دور) در یک صفحه وب است. این چیزی خیلی مفید نیست - تماس گیرنده و تماس گیرنده در یک صفحه هستند - اما عملکرد RTCPeerConnection
API را کمی واضح تر می کند زیرا اشیاء RTCPeerConnection
در صفحه می توانند داده ها و پیام ها را مستقیماً بدون نیاز به استفاده از سیگنال های واسطه مبادله کنند. مکانیسم ها
در این مثال، pc1
نشان دهنده همتای محلی (تماس گیرنده) و pc2
نشان دهنده همتای راه دور (callee) است.
تماس گیرنده
- یک
RTCPeerConnection
جدید ایجاد کنید و جریان را ازgetUserMedia()
اضافه کنید: ```js // Servers یک فایل پیکربندی اختیاری است. (بعداً بحث TURN و STUN را ببینید.) pc1 = new RTCPeerConnection(servers); // ... localStream.getTracks().forEach((Track) => { pc1.addTrack(track, localStream); });
- یک پیشنهاد ایجاد کنید و آن را به عنوان توضیحات محلی برای
pc1
و به عنوان توضیحات راه دور برایpc2
تنظیم کنید. این کار را می توان مستقیماً در کد بدون استفاده از سیگنالینگ انجام داد زیرا هر دو تماس گیرنده و تماس گیرنده در یک صفحه هستند:js pc1.setLocalDescription(desc).then(() => { onSetLocalSuccess(pc1); }, onSetSessionDescriptionError ); trace('pc2 setRemoteDescription start'); pc2.setRemoteDescription(desc).then(() => { onSetRemoteSuccess(pc2); }, onSetSessionDescriptionError );
کالی
-
pc2
ایجاد کنید و وقتی جریان ازpc1
اضافه شد، آن را در یک عنصر ویدیویی نمایش دهید:js pc2 = new RTCPeerConnection(servers); pc2.ontrack = gotRemoteStream; //... function gotRemoteStream(e){ vid2.srcObject = e.stream; }
RTCPeerConnection
API به علاوه سرورها
در دنیای واقعی، WebRTC به سرورهایی، هرچند ساده، نیاز دارد، بنابراین موارد زیر ممکن است اتفاق بیفتد:
- کاربران یکدیگر را کشف می کنند و جزئیات دنیای واقعی مانند نام ها را رد و بدل می کنند.
- برنامه های مشتری WebRTC (همتایان) اطلاعات شبکه را مبادله می کنند.
- همتایان دادهها را درباره رسانهها، مانند فرمت و وضوح ویدیو، تبادل میکنند.
- برنامه های مشتری WebRTC از دروازه ها و فایروال های NAT عبور می کنند.
به عبارت دیگر، WebRTC به چهار نوع عملکرد سمت سرور نیاز دارد:
- کشف و ارتباط کاربر
- سیگنال دهی
- پیمایش NAT/دیوار آتش
- سرورهای رله در صورتی که ارتباط همتا به همتا از کار بیفتد
پیمایش NAT، شبکه های همتا به همتا، و الزامات ساخت یک برنامه سرور برای کشف و سیگنال دهی کاربر، خارج از محدوده این مقاله است. کافی است بگوییم که پروتکل STUN و پسوند آن، TURN ، توسط چارچوب ICE برای فعال کردن RTCPeerConnection
برای مقابله با پیمایش NAT و سایر تغییرات شبکه استفاده می شود.
ICE چارچوبی برای اتصال همتایان، مانند دو مشتری چت ویدیویی است. در ابتدا، ICE سعی می کند تا همتایان را مستقیماً با کمترین تأخیر ممکن از طریق UDP متصل کند. در این فرآیند، سرورهای STUN یک وظیفه دارند: فعال کردن یک همتا در پشت NAT برای یافتن آدرس عمومی و پورت آن. (برای اطلاعات بیشتر در مورد STUN و TURN، به ساخت سرویس های پشتیبان مورد نیاز برای یک برنامه WebRTC مراجعه کنید.)
اگر UDP ناموفق باشد، ICE TCP را امتحان می کند. اگر اتصال مستقیم با مشکل مواجه شود - به ویژه به دلیل پیمایش NAT سازمانی و فایروال ها - ICE از یک سرور TURN واسطه (رله) استفاده می کند. به عبارت دیگر، ICE ابتدا از STUN با UDP برای اتصال مستقیم همتایان استفاده می کند و در صورت عدم موفقیت، به سرور رله TURN برمی گردد. عبارت finding kandidats به فرآیند یافتن رابط ها و پورت های شبکه اشاره دارد.
مهندس WebRTC جاستین اوبرتی اطلاعات بیشتری در مورد ICE، STUN و TURN در ارائه Google I/O WebRTC در سال 2013 ارائه می دهد. ( اسلایدهای ارائه نمونه هایی از اجرای سرور TURN و STUN را ارائه می دهند.)
یک کلاینت ساده چت ویدیویی
یک مکان خوب برای امتحان WebRTC، کامل با سیگنالینگ و پیمایش NAT/دیوار آتش با استفاده از سرور STUN، نسخه نمایشی چت ویدیویی در appr.tc است. این برنامه از adapter.js استفاده میکند، یک شیم برای ایزوله کردن برنامهها از تغییرات مشخصات و تفاوتهای پیشوندی.
کد عمداً در لاگ خود پرمخاطب است. برای درک ترتیب رویدادها، کنسول را بررسی کنید. در زیر شرح دقیق کد ارائه شده است.
توپولوژی های شبکه
WebRTC، همانطور که در حال حاضر پیاده سازی شده است، فقط از ارتباطات یک به یک پشتیبانی می کند، اما می تواند در سناریوهای شبکه پیچیده تر، مانند چندین همتا که هر یک مستقیماً با یکدیگر یا از طریق یک واحد کنترل چند نقطه (MCU) در ارتباط هستند، استفاده شود، سروری که می تواند تعداد زیادی از شرکت کنندگان را مدیریت کنید و ارسال جریانی انتخابی و میکس یا ضبط صدا و تصویر را انجام دهید.
بسیاری از برنامههای WebRTC موجود فقط ارتباط بین مرورگرهای وب را نشان میدهند، اما سرورهای دروازه میتوانند یک برنامه WebRTC را که روی مرورگر اجرا میشود، فعال کنند تا با دستگاههایی مانند تلفن (همچنین به عنوان PSTN شناخته میشود) و با سیستمهای VOIP تعامل داشته باشد. در می 2012، Doubango Telecom مشتری sipml5 SIP را که با WebRTC و WebSocket ساخته شده بود، منبع باز کرد، که (در میان سایر کاربردهای بالقوه) تماس های ویدیویی بین مرورگرها و برنامه های در حال اجرا در iOS و Android را امکان پذیر می کند. در Google I/O، Tethr و Tropo چارچوبی را برای ارتباطات بلایای طبیعی در یک کیف با استفاده از سلول OpenBTS برای فعال کردن ارتباطات بین تلفنهای ویژه و رایانهها از طریق WebRTC نشان دادند. ارتباط تلفنی بدون اپراتور!
RTCDataChannel
API<
علاوه بر صدا و تصویر، WebRTC از ارتباطات بلادرنگ برای انواع دیگر داده ها نیز پشتیبانی می کند.
RTCDataChannel
API تبادل همتا به همتای داده های دلخواه را با تاخیر کم و توان عملیاتی بالا امکان پذیر می کند. برای نمایشهای تک صفحهای و یادگیری نحوه ساخت یک برنامه ساده انتقال فایل، به ترتیب به نمونههای WebRTC و Codelab WebRTC مراجعه کنید.
موارد استفاده بالقوه زیادی برای API وجود دارد، از جمله:
- بازی
- برنامه های دسکتاپ از راه دور
- چت متنی بلادرنگ
- انتقال فایل
- شبکه های غیر متمرکز
API دارای چندین ویژگی برای استفاده حداکثری از RTCPeerConnection
و فعال کردن ارتباطات همتا به همتا قدرتمند و منعطف است:
- استفاده از تنظیمات جلسه
RTCPeerConnection
- چندین کانال به طور همزمان با اولویت بندی
- معناشناسی تحویل قابل اعتماد و غیر قابل اعتماد
- امنیت داخلی (DTLS) و کنترل ازدحام
- امکان استفاده با یا بدون صدا یا تصویر
سینتکس عمداً شبیه WebSocket با یک متد send()
و یک رویداد message
است:
const localConnection = new RTCPeerConnection(servers);
const remoteConnection = new RTCPeerConnection(servers);
const sendChannel =
localConnection.createDataChannel('sendDataChannel');
// ...
remoteConnection.ondatachannel = (event) => {
receiveChannel = event.channel;
receiveChannel.onmessage = onReceiveMessage;
receiveChannel.onopen = onReceiveChannelStateChange;
receiveChannel.onclose = onReceiveChannelStateChange;
};
function onReceiveMessage(event) {
document.querySelector("textarea#send").value = event.data;
}
document.querySelector("button#send").onclick = () => {
var data = document.querySelector("textarea#send").value;
sendChannel.send(data);
};
ارتباط مستقیم بین مرورگرها انجام میشود، بنابراین RTCDataChannel
میتواند بسیار سریعتر از WebSocket باشد، حتی اگر در هنگام سوراخ کردن برای مقابله با فایروالها و خرابی NAT، به سرور رله (TURN) نیاز باشد.
RTCDataChannel
در کروم، سافاری، فایرفاکس، اپرا و اینترنت سامسونگ در دسترس است. بازی Cube Slam از API برای برقراری ارتباط با وضعیت بازی استفاده می کند. بازی یک دوست یا بازی خرس! پلتفرم ابتکاری Sharefest امکان اشتراک گذاری فایل از طریق RTCDataChannel
و peerCDN را ارائه می دهد که چگونه WebRTC می تواند توزیع محتوای همتا به همتا را فعال کند.
برای اطلاعات بیشتر در مورد RTCDataChannel
، نگاهی به مشخصات پروتکل پیش نویس IETF بیندازید.
امنیت
چندین راه وجود دارد که یک برنامه یا افزونه ارتباطی بلادرنگ ممکن است امنیت را به خطر بیندازد. به عنوان مثال:
- رسانه ها یا داده های رمزگذاری نشده ممکن است بین مرورگرها یا بین مرورگر و سرور رهگیری شوند.
- ممکن است یک برنامه بدون اینکه کاربر بداند ویدیو یا صدا را ضبط و توزیع کند.
- بدافزار یا ویروسها ممکن است در کنار یک افزونه یا برنامه به ظاهر بیضرر نصب شوند.
WebRTC چندین ویژگی برای جلوگیری از این مشکلات دارد:
- پیاده سازی های WebRTC از پروتکل های امن مانند DTLS و SRTP استفاده می کنند.
- رمزگذاری برای تمام اجزای WebRTC، از جمله مکانیسم های سیگنالینگ، اجباری است.
- WebRTC یک افزونه نیست. اجزای آن در sandbox مرورگر اجرا می شوند و در یک فرآیند جداگانه اجرا نمی شوند. کامپوننت ها نیازی به نصب جداگانه ندارند و هر زمان که مرورگر به روز شود به روز می شوند.
- دسترسی دوربین و میکروفون باید به صراحت داده شود و هنگامی که دوربین یا میکروفون در حال اجرا است، این موضوع به وضوح توسط رابط کاربری نشان داده می شود.
بحث کامل در مورد امنیت برای رسانه های جریانی خارج از محدوده این مقاله است. برای اطلاعات بیشتر، به معماری امنیتی پیشنهادی WebRTC پیشنهاد شده توسط IETF مراجعه کنید.
در نتیجه
APIها و استانداردهای WebRTC می توانند ابزارهایی را برای ایجاد محتوا و ارتباطات، از جمله تلفن، بازی، تولید ویدیو، ساخت موسیقی و جمع آوری اخبار، دموکراتیک و غیرمتمرکز کنند.
تکنولوژی بیشتر از این مخرب نمی شود.
همانطور که وبلاگ نویس فیل ادهولم می گوید ، "به طور بالقوه، WebRTC و HTML5 می توانند همان تغییری را برای ارتباطات بلادرنگ ایجاد کنند که مرورگر اصلی برای اطلاعات انجام داد."
ابزارهای توسعه دهنده
- آمار WebRTC برای یک جلسه در حال انجام را می توان در این آدرس یافت:
- about://webrtc-internals در کروم
- opera://webrtc-internals در اپرا
- about:webrtc در فایرفاکس
- یادداشت های متقابل مرورگر
- adapter.js یک شیم جاوا اسکریپت برای WebRTC است که توسط Google با کمک انجمن WebRTC نگهداری می شود که پیشوندهای فروشنده، تفاوت های مرورگر و تغییرات مشخصات را خلاصه می کند.
- برای کسب اطلاعات بیشتر در مورد فرآیندهای سیگنال دهی WebRTC، خروجی گزارش appr.tc را به کنسول بررسی کنید.
- اگر همه چیز خیلی زیاد است، ممکن است ترجیح دهید از یک چارچوب WebRTC یا حتی یک سرویس کامل WebRTC استفاده کنید.
- گزارشهای اشکال و درخواستهای ویژگی همیشه قدردانی میشوند:
بیشتر بدانید
- جلسه WebRTC جاستین اوبرتی در Google I/O 2012
- آلن بی جانستون و دانیل سی. برنت یک کتاب WebRTC را اکنون در نسخه سوم آن در قالب های چاپی و کتاب الکترونیکی در webrtcbook.com نگهداری می کنند.
- webrtc.org خانه همه چیزهای WebRTC از جمله دموها، مستندات و بحث است.
- diskut-webrtc یک گروه گوگل برای بحث فنی WebRTC است.
- @webrtc
- اسناد Google Developers Talk اطلاعات بیشتری در مورد پیمایش NAT، STUN، سرورهای رله و جمع آوری نامزد ارائه می دهد.
- WebRTC در GitHub
- Stack Overflow مکان خوبی برای جستجوی پاسخ و پرسیدن سوالات در مورد WebRTC است.
استانداردها و پروتکل ها
- پیش نویس ویرایشگر WebRTC W3C
- پیش نویس ویرایشگر W3C: ضبط رسانه و جریان (همچنین به عنوان
getUserMedia
شناخته می شود) - منشور گروه کاری IETF
- پیش نویس پروتکل کانال داده IETF WebRTC
- پیش نویس IETF JSEP
- IETF استانداردی را برای ICE پیشنهاد کرد
- IETF RTCWEB کارگروه اینترنت-پیش نویس: موارد استفاده و الزامات ارتباطات بلادرنگ وب
خلاصه پشتیبانی WebRTC
MediaStream
و getUserMedia
API
- کروم دسکتاپ 18.0.1008 و بالاتر؛ کروم برای اندروید ۲۹ و بالاتر
- Opera 18 و بالاتر؛ اپرا برای اندروید 20 و بالاتر
- Opera 12، Opera Mobile 12 (بر اساس موتور Presto)
- فایرفاکس 17 و بالاتر
- مایکروسافت اج 16 و بالاتر
- Safari 11.2 و بالاتر در iOS و 11.1 و بالاتر در MacOS
- UC 11.8 و بالاتر در اندروید
- سامسونگ اینترنت 4 و بالاتر
RTCPeerConnection
API
- کروم دسکتاپ 20 و بالاتر؛ Chrome برای Android 29 و بالاتر (بدون پرچم)
- Opera 18 و بالاتر (به طور پیش فرض روشن)؛ Opera برای اندروید 20 و بالاتر (به طور پیش فرض روشن)
- فایرفاکس 22 و بالاتر (به طور پیش فرض روشن)
- مایکروسافت اج 16 و بالاتر
- Safari 11.2 و بالاتر در iOS و 11.1 و بالاتر در MacOS
- سامسونگ اینترنت 4 و بالاتر
RTCDataChannel
API
- نسخه آزمایشی در Chrome 25، اما پایدارتر (و با قابلیت همکاری فایرفاکس) در Chrome 26 و بالاتر. کروم برای اندروید ۲۹ و بالاتر
- نسخه پایدار (و با قابلیت همکاری فایرفاکس) در Opera 18 و بالاتر. اپرا برای اندروید 20 و بالاتر
- فایرفاکس 22 و بالاتر (به طور پیش فرض روشن)
برای اطلاعات بیشتر در مورد پشتیبانی بین پلتفرمی برای APIها، مانند getUserMedia
و RTCPeerConnection
، به caniuse.com و وضعیت پلتفرم Chrome مراجعه کنید.
APIهای بومی برای RTCPeerConnection
نیز در مستندات webrtc.org موجود است.