Windows.  Viruslar.  Noutbuklar.  Internet.  Idora.  Utilitalar.  Haydovchilar

Ushbu maqolaning maqsadi, uning tuzilishi va ishlash printsipi bilan tanishish uchun peer-to-peer video chatining (p2p video chat) demo namunasidan foydalanishdir. Shu maqsadda biz ko'p foydalanuvchili peer-to-peer video chat demo webrtc.io-demodan foydalanamiz. Uni quyidagi havoladan yuklab olish mumkin: https://github.com/webRTC/webrtc.io-demo/tree/master/site.

Shuni ta'kidlash kerakki, GitHub - bu veb-loyihalarni hamkorlikda ishlab chiqish uchun sayt yoki veb-xizmat. Unda ishlab chiquvchilar o'zlarining ishlanmalarining kodlarini joylashtirishlari, ularni muhokama qilishlari va bir-birlari bilan muloqot qilishlari mumkin. Bundan tashqari, ba'zi yirik IT kompaniyalari o'zlarining rasmiy omborlarini ushbu saytda joylashtiradilar. Xizmat ochiq kodli loyihalar uchun bepul manba kodi. GitHub ochiq, bepul manba kodli kutubxonalar uchun ombordir.

Shunday qilib, biz GitHub-dan yuklab olingan tengdoshlar orasidagi video suhbatning demo namunasini C diskiga joylashtiramiz. shaxsiy kompyuter"webrtc_demo" ilovamiz uchun yaratilgan katalogda.


Guruch. 1

Tuzilishidan (1-rasm) ko'rinib turibdiki, peer-to-peer video chat tilda amalga oshirilgan mijoz script.js va server server.js skriptlaridan iborat. JavaScript dasturlash. Skript (kutubxona) webrtc.io.js (CLIENT) - peer-to-peer sxemasidan foydalangan holda brauzerlar o'rtasida real vaqt rejimida aloqani tashkil qilishni ta'minlaydi: "mijoz-mijoz", va webrtc.io.js (CLIENT) va webrtc. io.js (SERVER), WebSocket protokolidan foydalanib, ular mijoz-server arxitekturasidan foydalangan holda brauzer va veb-server o'rtasida dupleks aloqani ta'minlaydi.

webrtc.io.js (SERVER) skripti webrtc.io kutubxonasiga kiritilgan va node_modules\webrtc.io\lib katalogida joylashgan. Video chat interfeysi index.html HTML5 va CSS3 da amalga oshiriladi. webrtc_demo ilova fayllarining mazmunini html muharrirlaridan biri yordamida ko'rish mumkin, masalan, "Notepad++".

Biz video suhbatning ishlash printsipini tekshiramiz fayl tizimi Kompyuter. Kompyuterda serverni (server.js) ishga tushirish uchun siz node.js ish vaqti muhitini o'rnatishingiz kerak. Node.js JavaScript kodini brauzerdan tashqarida ishlatish imkonini beradi. Siz node.js ni quyidagi havoladan yuklab olishingiz mumkin: http://nodejs.org/ (07/15/13 dan boshlab v0.10.13 versiyasi). Node.org veb-saytining asosiy sahifasida yuklab olish tugmasini bosing va http://nodejs.org/download/ saytiga o'ting. Uchun windows foydalanuvchilari avval win.installer (.msi) ni yuklab oling, so'ngra kompyuterda win.installer (.msi) ni ishga tushiring va Dastur fayllari katalogiga nodejs va "npm paket menejeri" ni o'rnating.




Guruch. 2

Shunday qilib, node.js JavaScript kodini ishlab chiqish va ishga tushirish uchun muhitdan, shuningdek, menejer yoki npm paket menejeri yordamida o'rnatilishi mumkin bo'lgan ichki modullar to'plamidan iborat.

Modullarni o'rnatish uchun siz kerak buyruq qatori Ilovalar katalogidan (masalan, "webrtc_demo") buyruqni bajaring: npm install module_name. Modullarni o'rnatish vaqtida npm menejeri o'rnatish amalga oshirilgan katalogda node_modules papkasini yaratadi. Ish paytida nodejs node_modules katalogidagi modullarni avtomatik ravishda bog'laydi.

Shunday qilib, node.js-ni o'rnatganingizdan so'ng, buyruq qatorini oching va npm paket menejeri yordamida webrtc_demo katalogining node_modules papkasida ekspress modulni yangilang:

C:\webrtc_demo>npm install express

Ekspress modul node.js uchun veb-ramka yoki ilovalarni ishlab chiqish uchun veb-platformadir. Ekspressga global kirish huquqiga ega bo'lish uchun uni quyidagi tarzda o'rnatishingiz mumkin: npm install -g express .

Keyin webrtc.io modulini yangilang:

C:\webrtc_demo>npm webrtc.io-ni o'rnating

Keyin buyruq satrida serverni ishga tushiramiz: server.js:

C:\webrtc_demo>tugun server.js


Guruch. 3

Mana, server muvaffaqiyatli ishlamoqda (3-rasm). Endi veb-brauzerdan foydalanib, siz IP-manzil bo'yicha server bilan bog'lanishingiz va index.html veb-sahifasini yuklashingiz mumkin, undan veb-brauzer mijoz skript kodini - script.js va webrtc.io.js skript kodini chiqaradi va ularni bajaring. Peer-to-peer video chatini boshqarish uchun (ikki brauzer o'rtasida aloqa o'rnatish uchun) webrtc-ni qo'llab-quvvatlaydigan ikkita brauzerdan node.js da ishlaydigan signal serveriga murojaat qilishingiz kerak.

Natijada, aloqa ilovasining mijoz qismining interfeysi (video chat) kamera va mikrofonga kirish uchun ruxsat so'rovi bilan ochiladi (4-rasm).



Guruch. 4

"Ruxsat berish" tugmasini bosgandan so'ng, kamera va mikrofon multimedia aloqasi uchun ulanadi. Bundan tashqari, siz video chat interfeysi orqali matnli ma'lumotlar orqali muloqot qilishingiz mumkin (5-rasm).



Guruch. 5

Shuni ta'kidlash kerak. Server signalizatsiya serveri bo'lib, asosan foydalanuvchi brauzerlari o'rtasida aloqa o'rnatish uchun mo'ljallangan. Node.js WebRTC signalini ta'minlovchi server.js server skriptini boshqarish uchun ishlatiladi.

WebRTC brauzer tomonidan taqdim etilgan API bo'lib, P2P ulanishini tashkil qilish va brauzerlar o'rtasida to'g'ridan-to'g'ri ma'lumotlarni uzatish imkonini beradi. Internetda o'zingizning video suhbatingizni qanday yozish bo'yicha juda ko'p qo'llanmalar mavjud WebRTC yordami. Misol uchun, bu erda Habré haqidagi maqola. Biroq, ularning barchasi ikkita mijozni ulash bilan cheklangan. Ushbu maqolada men WebRTC-dan foydalangan holda uch yoki undan ortiq foydalanuvchilar o'rtasida ulanish va xabar almashishni qanday tashkil qilish haqida gapirishga harakat qilaman.

RTCPeerConnection interfeysi ikkita brauzer o'rtasidagi tengdoshga ulanishdir. Uch yoki undan ortiq foydalanuvchini ulash uchun biz tarmoqli tarmoqni tashkil qilishimiz kerak (har bir tugun boshqa barcha tugunlarga ulangan tarmoq).
Biz quyidagi sxemadan foydalanamiz:

  • Sahifani ochishda biz location.hash-da xona identifikatorining mavjudligini tekshiramiz
  • Agar xona identifikatori ko'rsatilmagan bo'lsa, yangisini yarating
  • Biz signal serveriga ko'rsatilgan xonaga qo'shilishni xohlayotganimiz haqida xabar yuboramiz
  • Signal serveri ushbu xonadagi boshqa mijozlarga yangi foydalanuvchi haqida bildirishnoma yuboradi
  • Xonada bo'lgan mijozlar yangi kelganga SDP taklifini yuborishadi
  • Yangi boshlanuvchilar takliflarga javob beradi
  • 0. Signal serveri

    Ma'lumki, WebRTC brauzerlar o'rtasida P2P ulanish imkoniyatini taqdim etsa ham, uning ishlashi xizmat xabarlarini almashish uchun qo'shimcha transportni talab qiladi. Ushbu misolda foydalaniladigan transport socket.io yordamida Node.JS da yozilgan WebSocket serveridir:

    Var socket_io = talab ("socket.io"); module.exports = funktsiya (server) ( var users = (); var io = socket_io(server); io.on("ulanish", funktsiya(rozetka) ( // Xonaga yangi foydalanuvchi qo'shilishini xohlaysizmi socket.on( "room ", function(xabar) ( var json = JSON.parse(message); // foydalanuvchilar roʻyxatiga rozetka qoʻshing = socket; if (socket.room !== undefined) ( // Agar rozetka boʻlsa allaqachon ba'zi xonada , undan chiqish socket.leave(socket.room ) // socket.room = json.join(socket.room); yangi ishtirokchi socket.broadcast.to(socket.room).emit("new", json.id )); // WebRTC bilan bog'liq xabar (SDP taklifi, SDP javobi yoki ICE nomzodi) socket.on("webrtc", funksiya (xabar) ( var json = JSON.parse(message); if (json.to !== undefined && users !== undefined) ( // Agar xabarda serverga maʼlum boʻlgan qabul qiluvchi va oʻsha oluvchi koʻrsatilgan boʻlsa, biz joʻnatamiz. faqat unga xabar... users.emit("webrtc", xabar); ) else ( // ...aks holda biz xabarni socket.broadcast.to(socket.room).emit("webrtc", xabar; ) ) translyatsiya qilinadi deb hisoblaymiz); // Kimdir socket.on("disconnect", function() ni uzib qo'ydi ( // Mijoz uzilganda, bu haqda boshqalarga xabar bering socket.broadcast.to(socket.room).emit("leave", socket.user_id); foydalanuvchilarni o'chirish))) ))) );

    1.index.html

    Sahifaning o'zi uchun manba kodi juda oddiy. Men ataylab tartib va ​​boshqa go'zalliklarga e'tibor bermadim, chunki bu maqola bu haqda emas. Agar kimdir uni chiroyli qilishni xohlasa, bu qiyin bo'lmaydi.

    WebRTC Chat demosi 0 ta tengdoshga ulangan
    Yuborish

    2. main.js 2.0. Sahifa elementlari va WebRTC interfeyslariga havolalar olish var chatlog = document.getElementById("chatlog"); var message = document.getElementById("xabar"); var connection_num = document.getElementById("connection_num"); var room_link = document.getElementById("room_link");

    WebRTC interfeyslariga kirish uchun biz hali ham brauzer prefikslaridan foydalanishimiz kerak.

    Var PeerConnection = window.mozRTCPeerConnection || window.webkitRTCPeerConnection; var SessionDescription = window.mozRTCSessionDescription || window.RTCSessionDescription; var IceCandidate = window.mozRTCIceCandidate || window.RTCIceCandidate;

    2.1. Xona identifikatorini aniqlash

    Bu yerda bizga noyob xona va foydalanuvchi identifikatorini yaratish funksiyasi kerak. Ushbu maqsadlar uchun biz UUID dan foydalanamiz.

    Function uuid() ( var s4 = function() ( return Math.floor(Math.random() * 0x10000).toString(16); ); return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();

    Endi xona identifikatorini manzildan chiqarib olishga harakat qilaylik. Agar bittasi ko'rsatilmagan bo'lsa, biz yangisini yaratamiz. Keling, sahifada joriy xonaga havolani ko'rsatamiz va shu bilan birga joriy foydalanuvchining identifikatorini yaratamiz.

    Var ROOM = location.hash.substr(1); if (!ROOM) ( ROOM = uuid(); ) room_link.innerHTML = "Xonaga havola"; var ME = uuid();

    2.2. WebSocket

    Sahifani ochgandan so'ng biz signalizatsiya serverimizga ulanamiz, xonaga kirish uchun so'rov yuboramiz va xabarlarni qayta ishlovchilarni aniqlaymiz.

    // Xabarni yopayotganda serverga bu haqida bildirishnoma yuborish kerakligini ko'rsating var socket = io.connect("", ("sync disconnect on unload": true)); socket.on("webrtc", socketReceived); socket.on("yangi", socketNewPeer); // Darhol xonaga kirish so'rovini yuboring socket.emit("room", JSON.stringify((id: ME, xona: ROOM))); // Yordamchi funksiya WebRTC funksiyasi bilan bog‘liq manzilli xabarlarni yuborish uchun sendViaSocket(turi, xabar, kimga) ( socket.emit("webrtc", JSON.stringify((id: ME, kimga: uchun, turi: turi, ma'lumotlar: xabar))); )

    2.3. PeerConnection sozlamalari

    Aksariyat provayderlar NAT orqali Internetga ulanishni ta'minlaydi. Shu sababli, to'g'ridan-to'g'ri aloqa unchalik ahamiyatsiz masala emas. Ulanishni yaratishda biz brauzer NATni chetlab o'tish uchun foydalanishga harakat qiladigan STUN va TURN serverlari ro'yxatini ko'rsatishimiz kerak. Biz juftlikni ham ko'rsatamiz qo'shimcha imkoniyatlar ulanish uchun.

    Var server = ( iceServers: [ (url: "stun:23.21.150.121"), (url: "stun.l.google.com:19302"), (url: "turn:numb.viagenie.ca", hisob ma'lumotlari: "sizning parolingiz shu yerda", foydalanuvchi nomi: " [elektron pochta himoyalangan]") ] ); var options = ( ixtiyoriy: [ (DtlsSrtpKeyAgreement: true), // Chrome va Firefox oʻrtasida ulanish uchun zarur (RtpDataChannels: true) // DataChannels API-dan foydalanish uchun Firefox-da zarur ] )

    2.4. Yangi foydalanuvchi ulanish

    Xonaga yangi tengdosh qo'shilganda, server bizga yangi xabar yuboradi. Yuqoridagi xabarlarni qayta ishlovchilarga ko'ra, socketNewPeer funktsiyasi chaqiriladi.

    Var tengdoshlari = (); funktsiya socketNewPeer(data) ( peers = (candidateCache: ); // Yangi ulanish yaratish var pc = new PeerConnection(server, variantlar); // Uni ishga tushiring initConnection(kompyuter, ma'lumotlar, "taklif"); // Tengdoshlarni saqlash ro'yxat peers.connection = pc; // Xabarlar almashinadigan DataChannel yarating var channel = pc.createDataChannel("mychannel", ()channel = data peers.channel = channel bindEvents(channel); ; // SDP taklifini yaratish pc.createOffer(function(offer) ( pc.setLocalDescription(offer); ) ) function initConnection(pc, id, sdpType) ( pc.onicecandidate = funktsiya (voqea) ( if (event.candidate)) ( // Yangi ICE nomzodi aniqlanganda, uni peers.candidateCache.push(event.candidate ) keyingi yuborish uchun ro'yxatga qo'shing ( // Nomzod topilganda, ishlov beruvchi qayta chaqiriladi, lekin nomzodsiz // Bunday holda, biz birinchi navbatda tengdoshga SDP taklifini yoki SDP javobini yuboramiz (funktsiya parametriga qarab)... sendViaSocket(sdpType, pc.localDescription, id); // ...va keyin barcha ilgari topilgan ICE nomzodlari (var i = 0; i< peers.candidateCache.length; i++) { sendViaSocket("candidate", peers.candidateCache[i], id); } } } pc.oniceconnectionstatechange = function (event) { if (pc.iceConnectionState == "disconnected") { connection_num.innerText = parseInt(connection_num.innerText) - 1; delete peers; } } } function bindEvents (channel) { channel.onopen = function () { connection_num.innerText = parseInt(connection_num.innerText) + 1; }; channel.onmessage = function (e) { chatlog.innerHTML += "Peer says: " + e.data + ""; }; }

    2.5. SDP taklifi, SDP javobi, ICE nomzodi

    Ushbu xabarlardan birini olganimizda, biz mos keladigan xabar uchun ishlov beruvchini chaqiramiz.

    Function socketReceived(data) ( var json = JSON.parse(data); switch (json.type) ( case "candidate": remoteCandidateReceived(json.id, json.data); break; case "offer": remoteOfferReceived(json. id, json.data); "javob" holati: remoteAnswerReceived(json.id, json.data) )

    2.5.0 SDP taklif funksiyasi remoteOfferReceived(id, data) ( createConnection(id); var pc = peers.connection; pc.setRemoteDescription(new SessionDescription(data)); pc.createAnswer(function(javob) ( pc.setLocalDescription(javob) )); createConnection(id) ( if (peers === undefined) ( peers = (candidateCache: ); var pc = new PeerConnection(server, options); initConnection(pc, id, "javob"); peers.connection = pc; pc.ondatachannel = function(e) ( peers.channel = e.channel; peers.channel.owner = id; bindEvents(peers.channel); ) ) 2.5.1 SDP javob funksiyasi remoteAnswerReceived(id , data) ( var pc = peers.connection; pc.setRemoteDescription(new SessionDescription(data) ) 2.5.2 ICE nomzod funksiyasi remoteCandidateReceived(id, data) ( createConnection(id); var pc = peers.connection; pc. addIceCandidate(new IceCand) (ma'lumotlar)) 2.6. Xabar yuborilmoqda

    Send tugmasi bosilganda sendMessage funksiyasi chaqiriladi. Buning hammasi tengdoshlar ro'yxatidan o'tish va belgilangan xabarni hammaga yuborishga harakat qilishdir.

    Preambula. WebRTC asosidagi P2P video chat Skype va boshqa aloqa vositalariga muqobildir. WebRTC asosidagi p2p video chatining asosiy elementlari brauzer va kontakt serveridir. P2P video chatlari bir-biriga o'xshash video chatlar bo'lib, server uzatishda ishtirok etmaydi. axborot oqimlari

    . Ma'lumotlar to'g'ridan-to'g'ri foydalanuvchilarning brauzerlari (tengdoshlari) o'rtasida hech qanday qo'shimcha dasturlarsiz uzatiladi. Brauzerlardan tashqari, p2p video suhbatlari foydalanuvchilarni ro'yxatga olish, ular haqidagi ma'lumotlarni saqlash va foydalanuvchilar o'rtasida almashishni ta'minlash uchun mo'ljallangan kontakt serverlaridan foydalanadi. Eng so'nggi WebRTC va HTML5 texnologiyalarini qo'llab-quvvatlaydigan brauzerlar lahzali matnli xabarlar va fayllarni uzatishni, shuningdek IP tarmoqlari orqali ovozli va video aloqani ta'minlaydi.

    Aloqa xizmatlari ovozli, video, ma'lumotlar va matn kanallari birlashtirilmagan IMSdan tashqari ilovalardir. Har bir xizmat tarmoqlarida, . Shuni ta'kidlash kerakki, ushbu ilovalar bir vaqtning o'zida bir nechta aloqa tarmoqlarida ishlay olmaydi, ya'ni. Ilovalar odatda bir-biri bilan aloqa qila olmaydi, bu har bir aloqa tarmog'i uchun alohida dastur o'rnatilishini talab qiladi.

    Haqiqiy vaqtda aloqa xizmatlarini (chat, telefoniya, video konferentsiya) integratsiyalash muammosi, ya'ni. ovozli, video, ma’lumotlar kanallari integratsiyasi va ularga bitta ilova (brauzer) yordamida kirish WebRTC protokoli asosida peer-to-peer yoki p2p video chatlarida (peer-to-peer, point-to-point) hal qilinishi mumkin. Aslida, WebRTC-ni qo'llab-quvvatlaydigan brauzer barcha foydalanuvchi qurilmalari uchun yagona interfeysga aylanadi (kompyuterlar, smartfonlar, iPadlar, IP telefonlar, mobil telefonlar va hokazo) aloqa xizmatlari bilan ishlaydigan.

    Aynan WebRTC real vaqt rejimida aloqani ta'minlaydigan barcha texnologiyalarni brauzerda amalga oshirishni ta'minlaydi. P2p video suhbatlarining mohiyati shundan iboratki, multimedia va matnli ma'lumotlar to'g'ridan-to'g'ri foydalanuvchilarning brauzerlari (masofaviy peering) o'rtasida server yoki qo'shimcha dasturlar ishtirokisiz uzatiladi. Shunday qilib, brauzerlar nafaqat deyarli barchaga kirishni ta'minlaydi axborot resurslari Serverlarda saqlanadigan Internet, lekin ayni paytda barcha real vaqtda aloqa xizmatlariga kirish vositasiga aylanadi va pochta xizmatlari (ovozli pochta, elektron pochta, SMS va boshqalar)

    P2p video chatlarining serverlari (kontakt serverlari) faqat foydalanuvchilarni ro'yxatdan o'tkazish, foydalanuvchilar haqidagi ma'lumotlarni saqlash va foydalanuvchilarning brauzerlari o'rtasida ulanish (almashtirish) uchun mo'ljallangan. Birinchi p2p video chatlari flesh texnologiyalar yordamida amalga oshirildi. Flash p2p video chatlari, masalan, ishlatiladi ijtimoiy tarmoqlarda. Flash p2p video chatlari taqdim etilmaydi yuqori sifatli multimedia ma'lumotlarini uzatish. Bundan tashqari, p2p flesh video chatlarida mikrofon va videokameradan ovoz va video oqimini chiqarish uchun siz o'rnatishingiz kerak. flesh plagin veb-brauzerga.

    Ammo telekommunikatsiya xizmatlarining yangi avlodi Internet orqali muloqot qilish uchun faqat WebRTC protokollarini va HTML5 spetsifikatsiyasini qo'llab-quvvatlaydigan brauzerlar va aloqa serverlaridan foydalanadigan veb-muloqotlarni o'z ichiga oladi. Bunday brauzer bilan jihozlangan har qanday foydalanuvchi qurilmasi (kompyuter, iPad, smartfonlar va boshqalar) yuqori sifatli ovozli va video qo'ng'iroqlarni, shuningdek, tezkor matnli xabarlar va fayllarni uzatishni ta'minlaydi.

    Shunday qilib, veb-aloqa uchun yangi texnologiya (p2p chatlari, video chatlar) WebRTC protokoli. WebRTC HTML5, CSS3 va JavaScript bilan birgalikda turli veb-ilovalarni yaratishga imkon beradi. WebRT peer-to-peer arxitekturasidan foydalangan holda real vaqt rejimida veb-muloqotlarni (peer-to-peer tarmoqlari) tashkil qilish uchun mo'ljallangan. WebRTC asosidagi P2P chatlari brauzerda tashqi qo‘shimchalar va plaginlardan foydalanmasdan faqat veb-brauzerlardan foydalangan holda Internet orqali foydalanuvchilar o‘rtasida matn, ovozli va video aloqani ta’minlaydi.

    P2p chatlarida server faqat ikkita brauzer o'rtasida p2p ulanishini o'rnatish uchun ishlatiladi. WebRTC protokoli asosida p2p chatining mijoz qismini yaratish uchun HTML5, CSS3 va JavaScript ishlatiladi. Mijoz ilovasi WebRTC API orqali brauzerlar bilan o'zaro ishlaydi.

    WebRTC uchta JavaScript API tomonidan amalga oshiriladi:

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

    Brauzerlar media ma'lumotlarini UDP tepasida ishlaydigan SRTP protokoli yordamida uzatadi. NAT Internet orqali p2p ulanishlaridan foydalanadigan NAT routerlar ortidagi brauzerlar (mijozlar) uchun muammolarni keltirib chiqarganligi sababli, STUN NAT tarjimonlarini chetlab o'tish uchun ishlatiladi. STUN - yuqorida ishlaydigan mijoz-server protokoli transport protokoli UDP. P2p chatlarida, qoida tariqasida, umumiy STUN serveridan foydalaniladi va undan olingan ma'lumotlar, agar ular NAT orqasida bo'lsa, ikkita brauzer o'rtasida UDP ulanishi uchun ishlatiladi.

    WebRTC ilovalarini amalga oshirish misollari (p2p chatlari, ovozli va video veb-chatlar):
    1. WebRTC asosidagi P2P video chat Bistri (bir marta bosish video chat, p2p chat), Bistri-da ochilishi mumkin. Bistri brauzerda qo'shimcha dasturlar va plaginlarni o'rnatmasdan ishlaydi. Ishning mohiyati quyidagicha: ko'rsatilgan havoladan foydalanib p2p video chatini oching, ochilgan interfeysda ro'yxatdan o'tganingizdan so'ng, sheriklarni taklif qiling, so'ngra tengdosh mijozlar ro'yxatidan onlayn bo'lgan sherikni tanlang va "video qo'ng'iroq" tugmasini bosing. ” tugmasi.

    Natijada, MediaStream (getUserMedia) mikrofon + veb-kamerani suratga oladi va server tanlangan hamkor bilan signal xabarlarini almashadi. Signal xabarlarini almashgandan so'ng, PeerConnection API ovoz va video oqimlarini uzatish uchun kanallarni yaratadi. Bundan tashqari, Bistri tezkor matnli xabarlar va fayllarni uzatadi. Shaklda. 1 Bistri p2p video chat interfeysining skrinshotini ko'rsatadi.


    Guruch. 1. P2P video chat Bistri

    2. Twelephone (p2p video chat, p2p chat, SIP Twelephone) - bu mijoz ilovasi HTML5 va WebRTC asosida qurilgan bo'lib, u sizga ovozli va video qo'ng'iroqlarni amalga oshirish, shuningdek, tezkor matnli xabarlarni yuborish imkonini beradi, ya'ni. Twelephone test p2p chat, video chat va SIP Twelephone o'z ichiga oladi. Shuni ta'kidlash kerakki, Twelephone SIP protokolini qo'llab-quvvatlaydi va endi siz Twitter akkauntingizdan telefon raqami sifatida SIP telefonlaridan ovozli va video qo'ng'iroqlarni amalga oshirishingiz va qabul qilishingiz mumkin. Bundan tashqari, matnli xabarlar mikrofon orqali ovoz bilan kirishingiz mumkin va ovozni aniqlash dasturi matnni "Xabar yuborish" qatoriga kiritadi.

    Twelephone - brauzerga asoslangan veb-telefoniya Gugl xrom, 25-versiyasidan boshlab, qo'shimchasiz dasturiy ta'minot. Twelephone Chris Matthieu tomonidan ishlab chiqilgan. Server qismi Twelephone Node.js ustiga qurilgan. Server (kontakt serveri) faqat ikkita brauzer yoki WebRTC mijozlari o'rtasida p2p ulanishini o'rnatish uchun ishlatiladi. Twelephone ilovasi mavjud emas o'z mablag'lari avtorizatsiya, lekin hisob qaydnomasiga ulanishga qaratilgan ( hisob) Twitterda.

    Shaklda. 2-rasmda Twelephone p2p video chat interfeysining skrinshoti ko'rsatilgan.



    Guruch. 2. P2P teletelefon

    3. Guruh p2p video chat Conversat.io asosida qurilgan eng yangi texnologiyalar WebRTC va HTML5. Conversat video chati SimpleWebRTC kutubxonasi asosida ishlab chiqilgan va bir xonada 6 tagacha tengdosh mijozlar oʻrtasida muloqot qilish uchun moʻljallangan (muloqot uchun “Suhbatga nom berish” qatorida tengdosh mijozlar uchun umumiy xona nomini koʻrsating). P2P video chat Conversat foydalanuvchilarga kontakt serverida ro'yxatdan o'tmasdan aloqa xizmatlarini taqdim etadi. Shaklda. 3-rasmda Conversat p2p video chat interfeysining skrinshoti ko'rsatilgan.



    Guruch. 3. Guruh P2P video chat Conversat.io

    WebRTC asosidagi P2P video chatlarida ishtirok etish uchun foydalanuvchilar WebRTC protokoli va HTML5 spetsifikatsiyasini qo‘llab-quvvatlaydigan brauzer o‘rnatilgan bo‘lishi kerak. Hozirda Google brauzerlari 25-versiyasidan boshlab Chrome va Mozilla Firefox Nightly WebRTC protokoli va HTML5 spetsifikatsiyasini qo'llab-quvvatlaydi. WebRTC ilovalari tasvir va ovoz uzatish sifati jihatidan Flash ilovalaridan ustundir.

    Brauzerdan qo'ng'iroq qilish texnologiyalari ko'p yillar davomida mavjud: Java, ActiveX, Adobe Flash...So'nggi bir necha yil ichida plaginlar va tark etishi aniq bo'ldi virtual mashinalar Ular qulaylik bilan porlamaydi (nima uchun men hech narsa o'rnatishim kerak?) Va, eng muhimi, xavfsizlik bilan. Nima qilsa bo'ladi? Chiqish bor!

    Yaqin vaqtgacha IP-tarmoqlar IP telefoniya yoki video uchun bir nechta protokollardan foydalangan: SIP, eng keng tarqalgan protokol, H.323 va MGCP sahnadan chiqib ketish, Jabber/Jingle (Gtalk-da ishlatiladi), yarim ochiq Adobe RTMP* va, albatta. , Skype yopildi. Google tomonidan boshlangan WebRTC loyihasi IP va veb-telefoniya olamidagi vaziyatni o'zgartirishga harakat qilmoqda. dasturiy telefonlar, shu jumladan Skype. WebRTC shunchaki hamma narsani amalga oshirmaydi aloqa qobiliyatlari to'g'ridan-to'g'ri brauzer ichida, hozir deyarli har bir qurilmada o'rnatilgan, lekin ayni paytda brauzer foydalanuvchilari o'rtasidagi aloqaning umumiy muammosini hal qilishga harakat qiladi (turli xil ma'lumotlar almashinuvi, translyatsiya ekranlari, hujjatlar bilan hamkorlik qilish va boshqalar).

    Veb-ishlab chiquvchi nuqtai nazaridan WebRTC

    Veb-ishlab chiquvchi nuqtai nazaridan WebRTC ikkita asosiy qismdan iborat:

    • mahalliy resurslardan (kamera, mikrofon yoki ekran) media oqimlarini boshqarish mahalliy kompyuter) MediaStream obyektini qaytaruvchi navigator.getUserMedia usuli bilan amalga oshiriladi;
    • media oqimlarini ishlab chiqaruvchi qurilmalar o'rtasidagi tengdoshli aloqa, shu jumladan aloqa usullarini aniqlash va ularni to'g'ridan-to'g'ri uzatish - RTCPeerConnection ob'ektlari (audio va video oqimlarni yuborish va qabul qilish uchun) va RTCDataChannel (brauzerdan ma'lumotlarni yuborish va qabul qilish uchun).
    Nima qilamiz?

    Biz veb-rozetkalar yordamida WebRTC asosidagi brauzerlar o'rtasida oddiy ko'p foydalanuvchili video suhbatni qanday tashkil qilishni aniqlaymiz. Biz Chrome/Chromium-da tajriba o'tkazishni boshlaymiz, chunki WebRTC bo'yicha eng ilg'or brauzerlar, garchi 24 iyunda chiqarilgan Firefox 22 ular bilan deyarli yetib oldi. Aytish kerakki, standart hali qabul qilinmagan va API versiyadan versiyaga o'zgarishi mumkin. Barcha misollar Chromium 28 da sinovdan o'tkazildi. Oddiylik uchun biz kodning tozaligi va brauzerlar o'rtasidagi muvofiqligini nazorat qilmaymiz.

    MediaStream

    Birinchi va eng oddiy WebRTC komponenti bu MediaStream. Bu brauzerga mahalliy kompyuterning kamerasi va mikrofonidan media oqimlariga kirish imkonini beradi. Chrome'da buning uchun siz navigator.webkitGetUserMedia() funksiyasiga qo'ng'iroq qilishingiz kerak (standart hali yakunlanmaganligi sababli, barcha funktsiyalar prefiks bilan birga keladi va Firefox-da xuddi shu funksiya navigator.mozGetUserMedia() deb ataladi). Unga qo'ng'iroq qilganingizda, foydalanuvchidan kamera va mikrofonga kirishga ruxsat berish so'raladi. Qo‘ng‘iroqni faqat foydalanuvchi roziligi bilan davom ettirish mumkin bo‘ladi. Kerakli media oqimining parametrlari va ikkita qayta qo'ng'iroq funksiyasi ushbu funktsiyaga parametr sifatida uzatiladi: birinchisi, agar kamera/mikrofonga kirish muvaffaqiyatli bo'lsa, ikkinchisi - xatolik yuz berganda chaqiriladi. Birinchidan, tugma va elementli rtctest1.html HTML faylini yaratamiz:

    WebRTC - birinchi kirish videosi (balandligi: 240px; kengligi: 320px; chegara: 1px qattiq kulrang; ) getUserMedia

    Microsoft CU-RTC-Web

    Agar u CU-RTC-Web (html5labs.interoperabilitybridges.com/cu-rtc-web/cu-rtc-web) nomli mos kelmaydigan nostandart variantini chiqarish orqali Google tashabbusiga darhol javob bermasa, Microsoft Microsoft bo'lmas edi. htm). IE ulushi allaqachon kichik bo'lsa-da, pasayishda davom etsa-da, Skype foydalanuvchilari soni Microsoft-ga Google-ni siqib chiqarishga umid qilmoqda va bu aniq standart brauzerda qo'llanilishini taxmin qilish mumkin. Skype versiyalari. Google standarti birinchi navbatda brauzerlar o'rtasidagi aloqaga qaratilgan; shu bilan birga, ovozli trafikning asosiy qismi hali ham odatdagidek qolmoqda telefon tarmog'i, va u va IP tarmoqlari o'rtasidagi shlyuzlar nafaqat foydalanish qulayligi yoki tezroq tarqatish uchun, balki monetizatsiya vositasi sifatida ham zarurdir. Ko'proq ularni rivojlantirish uchun futbolchilar. Boshqa standartning paydo bo'lishi nafaqat ishlab chiquvchilarga bir vaqtning o'zida ikkita mos kelmaydigan texnologiyani qo'llab-quvvatlashga bo'lgan noxush ehtiyojga olib kelishi mumkin, balki kelajakda foydalanuvchiga mumkin bo'lgan funksionallik va mavjud texnik echimlarni kengroq tanlash imkonini beradi. Yashasak ko'ramiz.

    Mahalliy oqim yoqilmoqda

    HTML faylimiz teglari ichida media oqimi uchun global o'zgaruvchini e'lon qilaylik:

    Var localStream = null;

    GetUserMedia usulining birinchi parametri so'ralgan media oqimining parametrlarini ko'rsatishi kerak - masalan, oddiygina audio yoki videoni yoqing:

    Var streamConstraints = ("audio": rost, "video": rost); // Audio va videoga kirishni so'rash

    Yoki qo'shimcha parametrlarni belgilang:

    Var streamConstraints = ( "audio": rost, "video": ( "majburiy": ( "maxWidth": "320", "maxHeight": "240", "maxFrameRate": "5"), "ixtiyoriy": ) );

    GetUserMedia usulining ikkinchi parametri qayta qo'ng'iroq qilish funktsiyasiga o'tkazilishi kerak, agar u muvaffaqiyatli bo'lsa, chaqiriladi:

    Funktsiya getUserMedia_success(stream) ( console.log("getUserMedia_success():", stream); localVideo1.src = URL.createObjectURL(stream); // Media oqimini HTML elementiga ulang localStream = stream; // va saqlang keyingi foydalanish uchun global o'zgaruvchida)

    Uchinchi parametr - bu qayta qo'ng'iroq qilish funktsiyasi, xatolik yuz berganda chaqiriladigan xato ishlov beruvchisi

    getUserMedia_error(xato) funksiyasi ( console.log("getUserMedia_error():", xato); )

    GetUserMedia usuliga haqiqiy qo'ng'iroq birinchi tugma bosilganda mikrofon va kameraga kirish so'rovidir.

    getUserMedia_click() funksiyasi ( console.log("getUserMedia_click()"); navigator.webkitGetUserMedia(streamConstraints, getUserMedia_success, getUserMedia_error); )

    Mahalliy ochilgan fayldan media oqimiga kirish mumkin emas. Agar buni qilishga harakat qilsak, biz xatoga duch kelamiz:

    NavigatorUserMediaError (kod: 1, PERMISSION_DENIED: 1)"

    Olingan faylni serverga yuklaymiz, uni brauzerda ochamiz va paydo bo'lgan so'rovga javoban kamera va mikrofonga kirishga ruxsat beramiz.

    Chrome qaysi qurilmalarga kirishini Sozlamalar, Kengaytirilgan sozlamalarni ko‘rsatish havolasidan tanlashingiz mumkin. qo'shimcha sozlamalar"), Maxfiylik bo'limi ("Shaxsiy ma'lumotlar"), Kontent tugmasi ("Kontent sozlamalari"). IN Firefox brauzerlari va Opera, qurilmalar kirishga ruxsat berilganda to'g'ridan-to'g'ri ochiladigan ro'yxatdan tanlanadi.

    HTTP protokolidan foydalanilganda, sahifa yuklangandan keyin har safar media oqimiga kirishda ruxsat so'raladi. HTTPS ga o'tish so'rovni bir marta ko'rsatish imkonini beradi, faqat media oqimiga birinchi marta kirganingizda.

    Xatcho'p belgisidagi pulsatsiyalanuvchi doiraga va manzillar panelining o'ng tomonidagi kamera belgisiga e'tibor bering:

    RTMediaConnection

    RTTCMediaConnection - bu ishtirokchilar o'rtasida tarmoq orqali media oqimlarini o'rnatish va uzatish uchun mo'ljallangan ob'ekt. Bundan tashqari, ushbu ob'ekt media-sessiya tavsifini (SDP) yaratish, NAT yoki xavfsizlik devorlari (mahalliy va STUN-dan foydalanish) orqali o'tish uchun ICE nomzodlari haqida ma'lumot olish va TURN serveri bilan o'zaro aloqa qilish uchun javobgardir. Har bir ishtirokchida bitta ulanish uchun bitta RTCMediaConnection bo'lishi kerak. Media oqimlari shifrlangan SRTP protokoli yordamida uzatiladi.

    serverlarni TURN

    ICE nomzodlarining uch turi mavjud: xost, srflx va relay. Xost mahalliy qabul qilingan ma'lumotlarni o'z ichiga oladi, srflx tugun nimaga o'xshaydi tashqi server(STUN) va relay - TURN serveri orqali proksi-server trafigi uchun ma'lumot. Agar bizning tugunimiz NAT ortida bo'lsa, u holda xost nomzodlari mahalliy manzillarni o'z ichiga oladi va foydasiz bo'ladi, srflx nomzodlari faqat ma'lum turdagi NAT bilan yordam beradi va o'rni oraliq server orqali trafikni o'tkazish uchun oxirgi umid bo'ladi.

    192.168.1.37 manzili va udp/34022 portiga ega xost tipidagi ICE nomzodiga misol:

    A=nomzod:337499441 2 udp 2113937151 192.168.1.37 34022 tip xost avlodi 0

    STUN/TURN serverlarini belgilash uchun umumiy format:

    Var servers = ( "iceServers": [ ( "url": "stun:stun.stunprotocol.org:3478" ), ( "url": "turn:user@host:port", "credential": "parol" ) ]);

    Internetda ko'plab ommaviy STUN serverlari mavjud. Masalan, katta ro'yxat mavjud. Afsuski, ular juda kam muammolarni hal qilishadi. STUN-dan farqli o'laroq, ommaviy TURN serverlari deyarli yo'q. Buning sababi, TURN serveri media oqimlari orqali o'tadi, bu tarmoq kanalini ham, serverning o'zini ham sezilarli darajada yuklashi mumkin. Shuning uchun, TURN serverlariga ulanishning eng oson yo'li uni o'zingiz o'rnatishdir (shubhasiz, sizga umumiy IP kerak bo'ladi). Barcha serverlardan, mening fikrimcha, eng yaxshisi rfc5766-turn-server. Hatto Amazon EC2 uchun tayyor tasvir ham mavjud.

    TURN bilan hamma narsa biz xohlagan darajada emas, lekin faol rivojlanish davom etmoqda va umid qilmoqchimanki, bir muncha vaqt o'tgach, WebRTC, agar manzil tarjimasi (NAT) va xavfsizlik devorlari orqali o'tish sifati bo'yicha Skypega teng bo'lmasa. , hech bo'lmaganda sezilarli darajada yaqinlashadi.

    RTTCMediaConnection ulanishni o'rnatish uchun boshqaruv ma'lumotlarini almashish uchun qo'shimcha mexanizmni talab qiladi - garchi u bu ma'lumotlarni yaratsa ham, uni uzatmaydi va boshqa ishtirokchilarga uzatish alohida amalga oshirilishi kerak.


    O'tkazish usulini tanlash ishlab chiquvchiga tegishli - hech bo'lmaganda qo'lda. Kerakli ma'lumotlar almashinuvi amalga oshishi bilan RTTCediaConnection avtomatik ravishda media oqimlarini o'rnatadi (agar iloji bo'lsa, albatta).

    taklif-javob modeli

    Media oqimlarini o'rnatish va o'zgartirish uchun taklif/javob modeli (RFC3264 da tasvirlangan) va SDP (sessiya tavsifi protokoli) ishlatiladi. Ular SIP protokoli tomonidan ham qo'llaniladi. Ushbu modelda ikkita agent mavjud: Taklif - yangisini yaratish yoki mavjudini o'zgartirish uchun sessiyaning SDP tavsifini yaratuvchi (Offer SDP) va javob beruvchi - sessiyaning SDP tavsifini qabul qiluvchi. boshqa agent va o'z sessiya tavsifi bilan javob beradi (Javob SDP). Shu bilan birga, spetsifikatsiya dan ortiq protokolni talab qiladi yuqori daraja(masalan, SIP yoki veb-soketlar orqali mahalliy, bizning holatimizda bo'lgani kabi), agentlar o'rtasida SDP uzatish uchun javobgardir.

    Media oqimlarini muvaffaqiyatli o'rnatishi uchun ikkita RTTCediaConnection o'rtasida qanday ma'lumotlar uzatilishi kerak:

    • Ulanishni boshlagan birinchi ishtirokchi taklifni shakllantiradi, unda u SDP ma'lumotlar strukturasini uzatadi (bir xil protokol SIPda xuddi shu maqsadda qo'llaniladi), u uzatishni boshlayotgan media oqimining mumkin bo'lgan xususiyatlarini tavsiflaydi. Ushbu ma'lumotlar bloki ikkinchi ishtirokchiga o'tkazilishi kerak. Ikkinchi ishtirokchi SDP bilan javob tuzadi va uni birinchisiga yuboradi.
    • Birinchi va ikkinchi ishtirokchilar mumkin bo'lgan ICE nomzodlarini aniqlash tartibini amalga oshiradilar, uning yordamida ikkinchi ishtirokchi ularga media oqimini uzatishi mumkin. Nomzodlar aniqlanganda ular haqidagi ma'lumotlar boshqa ishtirokchiga uzatilishi kerak.

    Shakllantirish taklifi

    Taklif yaratish uchun bizga ikkita funksiya kerak. Birinchisi, agar u muvaffaqiyatli shakllantirilsa, chaqiriladi. CreateOffer() usulining ikkinchi parametri uni bajarish paytida xatolik yuz berganda chaqiriladigan qayta qo'ng'iroq qilish funktsiyasidir (agar mahalliy ip allaqachon mavjud).

    Bundan tashqari, ikkita hodisa ishlov beruvchisi kerak bo'ladi: yangi ICE nomzodini aniqlashda onicecandidate va uzoq tomondan media oqimini ulashda onaddstream. Keling, faylimizga qaytaylik. Elementli satrlardan keyin HTML ga yana bittasini qo'shamiz:

    taklif yaratish

    Va element bilan qatordan keyin (kelajak uchun):


    Shuningdek, JavaScript kodining boshida biz RTCPeerConnection uchun global o'zgaruvchini e'lon qilamiz:

    Var pc1;

    RTCPeerConnection konstruktoriga qo'ng'iroq qilishda siz STUN/TURN serverlarini ko'rsatishingiz kerak. Ular haqida ko'proq ma'lumot olish uchun yon panelga qarang; barcha ishtirokchilar bir tarmoqda ekan, ular talab qilinmaydi.

    Var serverlari = null;

    Taklif SDPni tayyorlash parametrlari

    Var offerConstraints = ();

    CreateOffer() usulining birinchi parametri Taklif muvaffaqiyatli shakllantirilgandan so'ng chaqiriladigan qayta qo'ng'iroq qilish funktsiyasidir

    Funktsiya pc1_createOffer_success(dec) ( console.log("pc1_createOffer_success(): \ndesc.sdp:\n"+desc.sdp+"desc:", desc); pc1.setLocalDescription(pasaytiruvchi); // Off RTCPeerConnection DP tomonidan yaratilgan setLocalDescription usulidan foydalanish // Uzoq tomon o'zining Answer SDP-ni yuborganda, uni setRemoteDescription usuli yordamida sozlash kerak bo'ladi // Ikkinchi tomon amalga oshirilgunga qadar biz hech narsa qilmaymiz // pc2_receivedOffer(dec);

    Ikkinchi parametr - bu xatolik yuz berganda chaqiriladigan qayta qo'ng'iroq qilish funktsiyasi

    Funktsiya pc1_createOffer_error(xato)( console.log("pc1_createOffer_success_error(): xato:", xato); )

    Va keling, ICE nomzodlari aniqlanganda o'tkaziladigan qayta qo'ng'iroq qilish funktsiyasini e'lon qilaylik:

    Funktsiya pc1_onicecandidate(event)( if (event.candidate) ( console.log("pc1_onicecandidate():\n"+ event.candidate.candidate.replace("\r\n", ""), event.candidate); // Ikkinchi tomon amalga oshirilmaguncha, biz hech narsa qilmaymiz // pc2.addIceCandidate(new RTCIceCandidate(event.candidate) ) )

    Shuningdek, uzoq tomondan media oqimini qo'shish uchun qayta qo'ng'iroq qilish funktsiyasi (kelajak uchun, chunki hozirda bizda faqat bitta RTCPeerConnection mavjud):

    Funktsiya pc1_onaddstream(event) ( console.log("pc_onaddstream()"); remoteVideo1.src = URL.createObjectURL(event.stream); )

    “CreateOffer” tugmasini bosganingizda, biz RTCPeerConnection-ni yaratamiz, onicecandidate va onaddstream usullarini o'rnatamiz va createOffer() usulini chaqirish orqali Taklif SDP yaratishni so'raymiz:

    Function createOffer_click() ( console.log("createOffer_click()"); pc1 = new webkitRTCPeerConnection(servers); // RTCPeerConnection yaratish pc1.onicecandidate = pc1_onicecandidate; // ICE nomzodlarini qayta ishlash uchun qayta qo'ng'iroq qilish funksiyasi //_1; pc1;amc1;onaddstreamc.amc. Uzoq tomondan media oqimi paydo bo'lganda chaqiriladigan qayta qo'ng'iroq funksiyasi hali yo'q pc1.addStream(localStream); Taklif pc1_createOffer_success , pc1_createOffer_error, offerConstraints ni shakllantirishni so'rang)

    Keling, faylni rtctest2.html sifatida saqlaymiz, uni serverga yuklaymiz, uni brauzerda ochamiz va uning ishlashi davomida qanday ma'lumotlar hosil bo'lishini konsolda ko'ramiz. Ikkinchi video hali chiqmaydi, chunki faqat bitta ishtirokchi bor. Eslatib o'tamiz, SDP - bu media-sessiya parametrlarining tavsifi, mavjud kodeklar, media oqimlari va ICE nomzodlari ma'lum bir ishtirokchiga ulanishning mumkin bo'lgan variantlari.

    Javob SDPni shakllantirish va ICE nomzodlarini almashish

    Taklif SDP va ICE nomzodlarining har biri boshqa tomonga o'tkazilishi kerak va u erda ularni olgandan so'ng, RTCPeerConnection taklif SDP uchun setRemoteDescription usullarini va uzoq tomondan olingan har bir ICE nomzodi uchun addIceCandidateni chaqiradi; xuddi shunday javob SDP va uzoq ICE nomzodlari uchun qarama-qarshi yo'nalishda. Javob SDPning o'zi Taklifga o'xshash tarzda tuzilgan; farqi shundaki, createOffer usuli emas, balki createAnswer usuli chaqiriladi va bundan oldin RTCPeerConnection usuli setRemoteDescription chaqiruvchidan olingan Taklif SDP ga uzatiladi.

    Keling, HTML-ga yana bir video element qo'shamiz:

    Va birinchisining deklaratsiyasi ostida ikkinchi RTCPeerConnection uchun global o'zgaruvchi:

    Var pc2;

    Taklif va javob SDP qayta ishlanmoqda

    Javob SDPning shakllanishi Taklifga juda o'xshaydi. Taklifga o'xshash javob muvaffaqiyatli shakllantirilgandan so'ng chaqiriladigan qayta qo'ng'iroq funksiyasida biz mahalliy tavsifni beramiz va olingan SDP javobini birinchi ishtirokchiga uzatamiz:

    Funktsiya pc2_createAnswer_success(tushirish) ( pc2.setLocalDescription(dec); console.log("pc2_createAnswer_success()", desc.sdp); pc1.setRemoteDescription(pastlash); )

    Javobni yaratishda xatolik yuz berganda chaqiriladigan qayta qo'ng'iroq qilish funksiyasi Taklifga mutlaqo o'xshaydi:

    Funktsiya pc2_createAnswer_error(xato) ( console.log("pc2_createAnswer_error():", xato); )

    Javob SDPni shakllantirish parametrlari:

    Var answerConstraints = ( "majburiy": ( "OfferToReceiveAudio":to'g'ri, "OfferToReceiveVideo":to'g'ri ) );

    Ikkinchi ishtirokchi taklifni olganida, biz RTCPeerConnection yaratamiz va Taklifga o'xshash tarzda Javobni shakllantiramiz:

    Funktsiya pc2_receivedOffer(desc) ( console.log("pc2_receiveOffer()", desc); // Birinchi ishtirokchiga o'xshab ikkinchi ishtirokchi uchun RTCPeerConnection ob'ektini yarating pc2 = yangi webkitRTCPeerConnection(serverlar); pc2.onicecandidateec =pc2.onecandidateec ; // ICE nomzodi paydo bo'lganda, uni o'rnating pc2.onaddstream = pc_onaddstream // Oqim paydo bo'lganda, uni HTML pc2.addStream (localStream) ga ulang (bizning misolimizda, ikkinchisi); ishtirokchi birinchisi bilan bir xil bo'ladi) // Endi, ikkinchi RTCPeerConnection tayyor bo'lgach, biz unga SDP taklifini o'tkazamiz (biz mahalliy oqimni birinchisiga o'tkazdik) pc2.setRemoteDescription(yangi RTCSessionDescription(tushirish)); // Javob xabari uchun ma'lumotlarni yaratish uchun ikkinchi ulanishni so'rash pc2.createAnswer(pc2_createAnswer_success, pc2_createAnswer_error, answerConstraints );

    Bizning misolimizda Offer SDP ni birinchi ishtirokchidan ikkinchisiga o'tkazish uchun uni pc1 funksiyasida izohdan olib tashlaymiz. taklif yaratish muvaffaqiyat() qo'ng'iroq liniyasi:

    Pc2_receivedOffer(pastlash);

    ICE nomzodlarini qayta ishlashni amalga oshirish uchun keling, birinchi ishtirokchi pc1_onicecandidate() ning ICE nomzodiga tayyorgarlik hodisasi ishlovchisida uning ikkinchisiga o'tkazilishini izohlaylik:

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

    Ikkinchi ishtirokchining ICE nomzodiga tayyorgarlik hodisasi boshqaruvchisi birinchisiga o'xshaydi:

    Funktsiya pc2_onicecandidate(event) ( if (event.candidate) ( console.log("pc2_onicecandidate():", event.candidate.candidate); pc1.addIceCandidate(yangi RTCIceCandidate(event.candidate)); ) )

    Birinchi ishtirokchidan media oqimini qo'shish uchun qayta qo'ng'iroq qilish funktsiyasi:

    Funktsiya pc2_onaddstream(event) ( console.log("pc_onaddstream()"); remoteVideo2.src = URL.createObjectURL(event.stream); )

    Ulanishni tugatish

    Keling, HTML ga yana bir tugma qo'shamiz

    Go'shakni qo'yish

    Va ulanishni to'xtatish funktsiyasi

    Funktsiya btnHangupClick() ( // Mahalliy videoni HTML elementlaridan uzing, mahalliy media oqimini to'xtating, o'rnating = null localVideo1.src = ""; localStream.stop(); localStream = null; // Har bir ishtirokchi uchun HTML-dan videoni o'chirib qo'ying. elementlar, ulanishni yoping, ko'rsatgichni o'rnating = null remoteVideo1.src = "" pc1 = remoteVideo2.src = "";

    Keling, uni rtctest3.html sifatida saqlab, serverga yuklaymiz va brauzerda ochamiz. Ushbu misol bitta brauzer yorlig'ida ikkita RTCPeerConnections o'rtasida media oqimlarini ikki tomonlama uzatishni amalga oshiradi. Tarmoq orqali ishtirokchilar o'rtasida Taklif va Javob SDP, ICE nomzodlari va boshqa ma'lumotlar almashinuvini tashkil qilish uchun to'g'ridan-to'g'ri qo'ng'iroq qilish tartib-qoidalari o'rniga, qandaydir transport turidan, bizning holatlarimizda - veb-rozetkalardan foydalangan holda ishtirokchilar o'rtasida almashinuvni amalga oshirish kerak bo'ladi.

    Ekranni quyish

    getUserMedia funktsiyasi, shuningdek, quyidagi parametrlarni belgilash orqali ekranni va oqimni MediaStream sifatida suratga olishi mumkin:

    Var mediaStreamConstraints = ( audio: noto'g'ri, video: ( majburiy: ( chromeMediaSource: "ekran"), ixtiyoriy: ) );

    Ekranga muvaffaqiyatli kirish uchun bir nechta shartlarga rioya qilish kerak:

    • getUserMedia() da chrome://flags/,chrome://flags/ da skrinshot bayrog'ini yoqish;
    • manba fayl HTTPS (SSL kelib chiqishi) orqali yuklab olinishi kerak;
    • audio oqim so'ralmasligi kerak;
    • Bir nechta so'rovlar bitta brauzer yorlig'ida bajarilmasligi kerak.
    WebRTC uchun kutubxonalar

    WebRTC hali tugallanmagan bo'lsa-da, unga asoslangan bir nechta kutubxonalar allaqachon paydo bo'lgan. JsSIP Asterisk va Camalio kabi SIP kalitlari bilan ishlaydigan brauzerga asoslangan dasturiy telefonlarni yaratish uchun mo'ljallangan. PeerJS ma'lumotlar almashinuvi uchun P2P tarmoqlarini yaratishni osonlashtiradi va Holla brauzerlardan P2P aloqasi uchun zarur bo'lgan rivojlanish hajmini kamaytiradi.

    Node.js va socket.io

    Tarmoq orqali ikkita RTCPeerConnections o'rtasida SDP va ICE nomzodlarini almashishni tashkil qilish uchun biz socket.io moduli bilan Node.js dan foydalanamiz.

    Node.js ning so‘nggi barqaror versiyasini (Debian/Ubuntu uchun) o‘rnatish tasvirlangan

    $ sudo apt-get o'rnatish python-software-properties python g++ make $ sudo add-apt-repository ppa:chris-lea/node.js $ sudo apt-get yangilanishi$ sudo apt-get install nodejs

    Boshqa operatsion tizimlar uchun o'rnatish tasvirlangan

    Keling, tekshiramiz:

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

    Npm (Node Package Manager) yordamida socket.io ni o'rnating va qo'shimcha modul ifoda eting:

    $ npm socket.io express-ni o'rnating

    Server tomoni uchun nodetest2.js faylini yaratish orqali uni sinab ko'raylik:

    $ nano nodetest2.js var app = require("express")() , server = require("http").createServer(app) , io = require("socket.io").listen(server); server.listen(80); // Agar 80-port bepul bo'lsa app.get("/", funksiya (req, res) ( // Ildiz sahifaga kirishda res.sendfile(__dirname + "/nodetest2.html"); // HTML faylni yuboring ) ); io.sockets.on("ulanish", funktsiya (rozetka) ( // socket.emit ("server hodisasi", ( salom: "world" )); // xabar yuboring socket.on("mijoz hodisasi" , funktsiya (ma'lumotlar) ( // va mijozdan xabar kelganda voqea ishlovchisini e'lon qilish console.log(data); ));

    Va mijoz tomoni uchun nodetest2.html:

    $ nano nodetest2.html var socket = io.connect("/"); // Websocket serverining URL manzili (sahifa yuklangan serverning ildiz sahifasi) socket.on("server hodisasi", funktsiya (ma'lumotlar) ( console.log(data); socket.emit("mijoz hodisasi", ( "nom": "qiymat" ));

    Serverni ishga tushiramiz:

    $ sudo nodejs nodetest2.js

    va brauzerda http://localhost:80 (agar 80-portda mahalliy ishlayotgan bo'lsa) sahifasini oching. Agar hamma narsa muvaffaqiyatli bo'lsa, konsolda Brauzer JavaScript ulanish paytida brauzer va server o'rtasida voqealar almashinuvini ko'ramiz.

    RTCPeerConnection o'rtasida veb-rozetkalar orqali ma'lumot almashish Mijoz qismi

    Keling, asosiy misolimizni (rtcdemo3.html) yangi rtcdemo4.html nomi bilan saqlaymiz. Elementga socket.io kutubxonasini qo'shamiz:

    Va JavaScript skriptining boshida - veb-soketlarga ulanish:

    Var socket = io.connect("http://localhost");

    Keling, boshqa ishtirokchining funktsiyalariga to'g'ridan-to'g'ri qo'ng'iroqni unga veb-rozetkalar orqali xabar yuborish orqali almashtiraylik:

    Function createOffer_success(desc) ( ... // pc2_receivedOffer(pasayish); socket.emit("offer", desc); ... ) funktsiyasi pc2_createAnswer_success(pasaytiruvchi) ( ... // pc1.setRemoteDescription(pasayish); socket .emit("javob", desc); ) funktsiyasi pc1_onicecandidate(voqe) ( ... // pc2.addIceCandidate(yangi RTCIceCandidate(voqe.kandidate)); socket.emit("ice1", event.candidate); .. ) funktsiyasi pc2_onicecandidate(event) ( ... // pc1.addIceCandidate(yangi RTCIceCandidate(event.candidate)); socket.emit("ice2", event.candidate); ... )

    hangup() funksiyasida ikkinchi ishtirokchining funksiyalarini to'g'ridan-to'g'ri chaqirish o'rniga biz veb-rozetkalar orqali xabarni uzatamiz:

    Funktsiya btnHangupClick() ( ... // remoteVideo2.src = ""; pc2.close(); pc2 = null; socket.emit("hangup", ()); )

    Va xabarlarni qabul qiluvchi ishlovchilarni qo'shing:

    Socket.on("taklif", funksiya (ma'lumotlar) ( console.log("socket.on("taklif"):", ma'lumotlar); pc2_receivedOffer(ma'lumotlar); )); socket.on("javob", funksiya (ma'lumotlar) (e console.log("socket.on("javob"):", ma'lumotlar); pc1.setRemoteDescription(yangi RTCSessionDescription(ma'lumotlar)); )); socket.on("ice1", funktsiya (ma'lumotlar) ( console.log("socket.on("ice1"):", ma'lumotlar); pc2.addIceCandidate(yangi RTCIceCandidate(ma'lumotlar)); )); socket.on("ice2", funktsiya (ma'lumotlar) ( console.log("socket.on("ice2"):", ma'lumotlar); pc1.addIceCandidate(yangi RTCIceCandidate(ma'lumotlar)); )); socket.on("hangup", funktsiya (ma'lumotlar) ( console.log("socket.on("hangup"):", ma'lumotlar); remoteVideo2.src = ""; pc2.close(); pc2 = null; ) );

    Server qismi

    Server tomonida nodetest2 faylini rtctest4.js yangi nomi ostida saqlang va io.sockets.on("ulanish", funktsiya (rozetka) ( ... ) funktsiyasi ichida biz mijoz xabarlarini qabul qilish va yuborishni qo'shamiz:

    Socket.on("taklif", funktsiya (ma'lumotlar) ( // "taklif" xabarini olayotganda, // mijoz aloqasi o'rnatilganligi sababli bu misolda faqat bitta narsa, // xabarni bir xil socket orqali yuboring.emit("taklif", ma'lumotlar); // Agar xabarni barcha ulanishlar orqali yuborish kerak bo'lsa // jo'natuvchidan tashqari: // soket.broadcast.emit("taklif", ma'lumotlar); ))) socket.on("javob", funksiya (ma'lumotlar) ( socket.emit("javob", ma'lumotlar); )); socket.on("ice1", funktsiya (ma'lumotlar) ( socket.emit("ice1", ma'lumotlar); )); socket.on("ice2", funktsiya (ma'lumotlar) ( socket.emit("ice2", ma'lumotlar); )); socket.on("hangup", funktsiya (ma'lumotlar) ( socket.emit("hangup", data); ));

    Bundan tashqari, HTML fayl nomini o'zgartiramiz:

    // res.sendfile(__dirname + "/nodetest2.html"); // HTML faylni yuboring res.sendfile(__dirname + "/rtctest4.html");

    Serverni ishga tushirish:

    $ sudo nodejs nodetest2.js

    Ikkala mijozning kodi bitta brauzer yorlig'ida bajarilganiga qaramay, bizning misolimizdagi ishtirokchilar o'rtasidagi barcha o'zaro aloqalar butunlay tarmoq orqali amalga oshiriladi va ishtirokchilarni "ajratish" hech qanday maxsus qiyinchiliklarni talab qilmaydi. Biroq, biz qilgan ish ham juda oddiy edi - bu texnologiyalar yaxshi, chunki ulardan foydalanish oson. Ba'zida aldamchi bo'lsa ham. Xususan, STUN/TURN serverlarisiz bizning misolimiz manzil tarjimasi va xavfsizlik devorlari mavjud bo'lganda ishlamasligini unutmasligimiz kerak.

    Xulosa

    Olingan misol juda an'anaviy, lekin agar biz hodisa ishlov beruvchilarini qo'ng'iroq qiluvchi va chaqiruvchi tomon o'rtasida farq qilmasligi uchun biroz universallashtirsak, ikkita pc1 va pc2 ob'ektlari o'rniga RTCPeerConnection massivini yarating va amalga oshiring. dinamik yaratish va elementlarni olib tashlasangiz, siz butunlay foydalanish mumkin bo'lgan video suhbatga ega bo'lasiz. WebRTC bilan bog'liq hech qanday maxsus xususiyatlar mavjud emas va bir nechta ishtirokchilar uchun oddiy video suhbatning namunasi (shuningdek, maqoladagi barcha misollarning matnlari) jurnal bilan birga kelgan diskda. Biroq, Internetda allaqachon ko'plab yaxshi misollarni topishingiz mumkin. Xususan, maqolani tayyorlashda quyidagilardan foydalanilgan: simpl.info getUserMedia, simpl.info RTCPeerConnection, WebRTC Reference App.

    Taxmin qilish mumkinki, juda tez orada WebRTC tufayli nafaqat ovozli va video aloqalarni tushunishimizda, balki butun Internetni idrok etishda ham inqilob bo'ladi. WebRTC nafaqat brauzerdan brauzerga qo'ng'iroq qilish texnologiyasi, balki real vaqtda aloqa texnologiyasi sifatida ham joylashtirilgan. Biz muhokama qilgan video aloqa faqat kichik bir qismdir mumkin bo'lgan variantlar uning ishlatilishi. Skrinkasting va hamkorlik misollari, hatto RTCDataChannel yordamida brauzerga asoslangan P2P kontentni yetkazib berish tarmog'i allaqachon mavjud.

    Bugungi kunda WebRTC brauzerlarda audio va videolarni oqimlash uchun "issiq" texnologiyadir. HTTP Streaming va Flash kabi konservativ texnologiyalar yozib olingan kontentni (talab bo'yicha video) tarqatish uchun ko'proq mos keladi va real vaqt va onlayn eshittirishlar nuqtai nazaridan WebRTC dan sezilarli darajada past bo'ladi, ya'ni. bu erda tomoshabinlarga nima bo'layotganini "jonli" ko'rishga imkon berish uchun minimal video kechikishi talab qilinadi.

    Haqiqiy vaqtda yuqori sifatli aloqa qilish imkoniyati WebRTC arxitekturasining o'zidan kelib chiqadi, u foydalanadi UDP protokoli, bu videoni minimal kechikish bilan uzatish uchun standart asos bo'lib, real vaqtda aloqa tizimlarida keng qo'llaniladi.

    Aloqa kechikishi onlayn eshittirish tizimlarida, vebinarlarda va video manba, oxirgi foydalanuvchilar bilan interaktiv aloqani talab qiluvchi va yechimni talab qiluvchi boshqa ilovalarda muhim ahamiyatga ega.

    WebRTC-ni sinab ko'rishning yana bir yaxshi sababi shundaki, bu, albatta, trend. Bugun hamma Android Chrome brauzer ushbu texnologiyani qo'llab-quvvatlaydi, bu esa millionlab qurilmalarni hech qanday qo'shimcha dasturiy ta'minot yoki konfiguratsiyalarni o'rnatmasdan ko'rishga tayyorligini kafolatlaydi.

    WebRTC texnologiyasini amalda sinab ko'rish va unda oddiy onlayn translyatsiyani ishga tushirish uchun biz Flashphoner WebRTC Media & Broadcasting Server server dasturidan foydalandik. Xususiyatlar WebRTC oqimlarini bittadan ko'p rejimida translyatsiya qilish imkoniyatini, shuningdek, RTSP protokoli orqali IP kameralar va video kuzatuv tizimlarini qo'llab-quvvatlashni bildiradi; Ushbu sharhda biz veb-eshittirishlar va ularning xususiyatlariga e'tibor qaratamiz.

    WebRTC Media & Broadcasting Server o'rnatilmoqda

    Chunki uchun Windows tizimlari server versiyasi yo'q edi va men VMWare+Linux kabi virtual mashinani o'rnatishni xohlamadim, shuning uchun men uyda onlayn translyatsiyalarni sinab ko'rishim mumkin edi Windows kompyuter Ishdan chiqmadi. Vaqtni tejash uchun biz bulutli xostingdan quyidagi misolni olishga qaror qildik:

    Bu Amsterdam ma'lumotlar markazida oldindan o'rnatilgan dasturiy ta'minotsiz Centos x86_64 6.5 versiyasi edi. Shunday qilib, bizning ixtiyorimizda faqat server va unga ssh kirish imkoniyati mavjud. Bilganlar uchun konsol buyruqlari Linux, WebRTC serverini o'rnatish oddiy va og'riqsiz bo'lishni va'da qiladi. Shunday qilib, biz nima qildik:

    1. Arxivni yuklab oling:

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

    2. Paketdan chiqarish:

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

    3. O'rnatish:

    $cd FlashphonerWebCallServer

    O'rnatish vaqtida server IP manzilini kiriting: XXX.XXX.XXX.XXX

    4. Litsenziyani faollashtiring:

    $cd /usr/local/FlashphonerWebCallServer/bin

    $./activation.sh

    5. WCS serverini ishga tushiring:

    $service webcallserver ishga tushirildi

    6. Jurnalni tekshiring:

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

    7. Ikki jarayonning mavjudligini tekshiring:

    $ps aux | grep Flashphoner

    Oʻrnatish jarayoni tugallandi.

    WebRTC onlayn eshittirishlarini sinovdan o'tkazish

    Eshittirishlarni sinovdan o'tkazish oddiy masala bo'lib chiqdi. Serverga qo'shimcha ravishda o'nlab Javascript, HTML va CSS fayllaridan iborat veb-mijoz mavjud va biz o'rnatish bosqichida /var/www/html jildiga joylashtirdik. Qilinishi kerak bo'lgan yagona narsa, veb-mijoz HTML5 Websockets orqali server bilan aloqa o'rnatishi uchun serverning IP-manzilini flashphoner.xml konfiguratsiyasiga kiritish edi. Keling, sinov jarayonini tasvirlab beraylik.

    1. Indeks.html test mijoz sahifasini oching Chrome brauzeri e:

    2. Efirni boshlash uchun ekranning o'rtasida joylashgan "Start" tugmasini bosishingiz kerak.
    Buni amalga oshirishdan oldin, veb-kamera ulangan va foydalanishga tayyor ekanligiga ishonch hosil qilishingiz kerak. Veb-kamera uchun maxsus talablar yo'q, masalan, biz 1280x800 o'lchamli noutbukga o'rnatilgan standart kameradan foydalandik.

    Chrome brauzeri, albatta, kamera va mikrofonga kirishni so'raydi, shunda foydalanuvchi o'z videosi Internet-serverga yuborilishini tushunadi va unga ruxsat beradi.

    3. Interfeys video oqimining kameradan WebRTC serveriga muvaffaqiyatli uzatilishini ifodalaydi. Yuqori o'ng burchakda indikator oqim serverga ketayotganini ko'rsatadi, pastki burchakda videoni yuborishni to'xtatish uchun "To'xtatish" tugmasi mavjud.

    Quyidagi qutidagi havolaga e'tibor bering. Unda ushbu oqim uchun noyob identifikator mavjud, shuning uchun har kim tomoshaga qo'shilishi mumkin. Shunchaki brauzeringizda ushbu havolani oching. Uni vaqtinchalik xotiraga nusxalash uchun "Nusxalash" tugmasini bosing.

    Vebinarlar, ma'ruzalar, onlayn video eshittirishlar yoki interaktiv televidenie kabi haqiqiy ilovalarda ishlab chiquvchilar ushbu identifikatorni ma'lum tomoshabinlar guruhlariga kerakli oqimlarga ulanishlari uchun tarqatishni amalga oshirishlari kerak, ammo bu allaqachon dastur mantig'i. . WebRTC Media & Broadcasting Server unga ta'sir qilmaydi, faqat videoni tarqatadi.

    5. Ulanish o'rnatildi va tomoshabin ekranda oqimni ko'radi. Endi u havolani boshqa birovga yuborishi, oqim o‘ynashni to‘xtatishi yoki yoqishi mumkin to'liq ekran rejimi, pastki o'ng burchakdagi boshqaruv elementlaridan foydalaning.

    WebRTC onlayn eshittirish serverini sinovdan o'tkazish natijalari

    Sinovlar paytida kechikish mukammal bo'lib tuyuldi. Ma'lumotlar markaziga ping taxminan 100 millisekundni tashkil etdi va kechikish ko'zga ko'rinmas edi. Bu erdan biz haqiqiy kechikish buferlash vaqti uchun bir xil 100 plyus yoki minus bir necha o'nlab millisekundlar deb taxmin qilishimiz mumkin. Flash video bilan solishtirganda: bunday testlarda Flash WebRTC kabi yaxshi ishlamaydi. Shunday qilib, agar siz xuddi shunday tarmoqqa qo'lingizni harakatlantirsangiz, ekrandagi harakat faqat bir yoki ikki soniyadan keyin ko'rinadi.

    Sifatga kelsak, kublar ba'zan harakatlar bilan ajralib turishi mumkinligini ta'kidlaymiz. Bu VP8 kodekining tabiatiga va uning asosiy maqsadiga mos keladi - qabul qilinadigan sifatli va aloqa kechikishlarisiz real vaqt rejimida video aloqani ta'minlash.

    Serverni o'rnatish va sozlash juda oson, uni ishga tushirish ssh orqali konsoldan buyruqlarni bajara oladigan va undan foydalanishi mumkin bo'lgan ilg'or foydalanuvchi darajasida Linuxni bilishdan boshqa jiddiy ko'nikmalarni talab qilmaydi; matn muharriri. Natijada, biz brauzerlar o'rtasida birdan ko'p onlayn translyatsiyani o'rnatishga muvaffaq bo'ldik. Qo'shimcha tomoshabinlarni oqimga ulash ham hech qanday muammo tug'dirmadi.

    Eshittirish sifati vebinarlar va onlayn translyatsiyalar uchun juda maqbul bo'lib chiqdi. Ba'zi savollar tug'dirgan yagona narsa video rezolyutsiyasi edi. Kamera 1280x800 o'lchamini qo'llab-quvvatlaydi, ammo sinov tasviridagi piksellar soni 640x480 ga juda o'xshaydi. Ko'rinishidan, bu masalani ishlab chiquvchilar bilan aniqlashtirish kerak.

    Veb-kameradan translyatsiyani sinovdan o'tkazish bo'yicha video
    WebRTC serveri orqali

    Agar xatolikni sezsangiz, matn qismini tanlang va Ctrl+Enter tugmalarini bosing
    ULOSING: