WebRTC PeCConnection рдФрд░ DataChannel: рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдХреЗ рдмреАрдЪ рдбреЗрдЯрд╛ рд╡рд┐рдирд┐рдордп

рдЫрд╡рд┐

рдХрдИ рд▓реЛрдЧреЛрдВ рдиреЗ WebRTC рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реБрдирд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдирд╣реАрдВ рдЧрдпрд╛ред рджреВрд╕рд░реЗ рджрд┐рди рдореИрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдХреЗ рдмреАрдЪ рд╕рдВрджреЗрд╢ рднреЗрдЬрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдФрд░ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рдЖрджрд┐рдо рдкреА 2 рдкреА рдЪреИрдЯ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рдкреНрд░рдпреЛрдЧ рдПрдХ рд╕рдлрд▓рддрд╛ рдереА, рдФрд░ рдореЗрд░реЗ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореИрдВрдиреЗ рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ред рд╡реАрдбрд┐рдпреЛ рдкреНрд░рд╕рд╛рд░рдг рдХреЗ рд▓рд┐рдП WebRTC рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдореБрджреНрджреЛрдВ рдХреЛ рдХрд╡рд░ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ Habr├й рдкрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓реЗрдЦ рдереЗ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ (рдФрд░ рдЕрдВрддрд┐рдо) рдкрд╛рда рдпрд╛ рдмрд╛рдЗрдирд░реА рдбреЗрдЯрд╛ рдХреЗ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддрд╛ рдерд╛ред

рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рдмреАрдЪ рд╕рдВрдЪрд╛рд░ рдХреЗ рд▓рд┐рдП, рд╣рдо RTCPeerConnection (рдХрдиреЗрдХреНрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП) рдФрд░ RTCDataChannel (рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╣рдореЗрдВ RTCIceCandidate рдФрд░ RTCSessionDescription рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдмрд╛рдж рдореЗрдВ рдЙрд╕ рдкрд░ рдФрд░ рдЕрдзрд┐рдХред

DataChannel рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХреЗ рд▓рд┐рдП рд╕рдорд░реНрдерди рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕рдм рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ Firefox 19+ рдпрд╛ Chrome 25+ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ <22 рдореЗрдВ WebRTC рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЕрдХреНрд╖рдо рд╣реИ (рдЖрдкрдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдореАрдбрд┐рдпрд╛рдЧреНрд░рд╛рдЙрдВрдбрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рддреНрдп рдХреЗ рд▓рд┐рдП рд╕рдХреНрд╖рдо рд╣реИ), рдФрд░ Chrome 25 рдХреЛ -рдиреЗрдмрд▓-рдбреЗрдЯрд╛-рдЪреИрдирд▓ рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдкреАрдЫреЗ рдирд╣реАрдВ рджреЗрдЦрд╛, рдФрд░ рдпрд╣ рдкреЛрд╕реНрдЯ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ 22+ рдФрд░ рдХреНрд░реЛрдо 26+ рдкрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╣реИред рдУрдкреЗрд░рд╛ 15 рдореЗрдВ WebRTC рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рд╣реИред

рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВ


рдЪреВрдВрдХрд┐ рдпрд╣ рд╕рдм рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЕрдзреАрди рд╣реИ рдФрд░ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдФрд░ рдХреНрд░реЛрдо рдореЗрдВ рдбрд┐рдЬрд╛рдЗрдирд░реЛрдВ рдХреЗ рдкрд╛рд╕ рдХреНрд░рдорд╢рдГ рдореЛрдЬ рдФрд░ рд╡реЗрдмрдХрд┐рдЯ рдЙрдкрд╕рд░реНрдЧ рд╣реИрдВ, рдЪрд▓реЛ рдереЛрдбрд╝рд╛ рдЖрджреЗрд╢ рд▓рд╛рдПрдВ:

window._RTCPeerConnection = window.webkitPeerConnection00 || window.webkitRTCPeerConnection || window.mozRTCPeerConnection || window.RTCPeerConnection || window.PeerConnection; window._RTCIceCandidate = window.webkitRTCIceCandidate || window.mozRTCIceCandidate || window.RTCIceCandidate; window._RTCSessionDescription = window.webkitRTCSessionDescription || window.mozRTCSessionDescription || window.RTCSessionDescription; 

рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдФрд░ рдХреНрд░реЛрдо рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЖрдЬ рднрд┐рдиреНрди рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

 var browser = { mozilla: /firefox/i.test(navigator.userAgent), chrome: /chrom(e|ium)/i.test(navigator.userAgent) }; 

рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдПрдХ-рджреВрд╕рд░реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ "рд╕рд┐рдЧреНрдирд▓" рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИ, рдЬрд┐рд╕реЗ рд╡реЗрдмрдЖрд░рдЯреАрд╕реА рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рдПрдХ рд╕рд░реНрд╡рд░ рд╣реИ рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЧреНрд░рд╛рд╣рдХ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реАрдЦрддреЗ рд╣реИрдВ рдФрд░ рд╕реВрдЪрдирд╛рдУрдВ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рд╡реЗ рдПрдХ рд╕реАрдзрд╛ рд╕рдВрдмрдВрдз рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдЪрд┐рддреНрд░ рдореБрдЭреЗ рдпрд╣рд╛рдБ рд╕реЗ рдЙрдзрд╛рд░ рд▓рд┐рдП рдЧрдП рдЪрд┐рддреНрд░рдг рдореЗрдВ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ :

рдЫрд╡рд┐


рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВрдиреЗ рдиреЛрдб рдкрд░ рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП WebSocket рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдерд╛ред рдпрджрд┐ рдпрд╣ рдПрдХ рдЪреИрдЯ рд╣реИ, рддреЛ рд╣рдорд╛рд░рд╛ рд╕рд░реНрд╡рд░ рдкреНрд░рддреНрдпреЗрдХ рдХрдиреЗрдХреНрдЯ рдХрд┐рдП рдЧрдП рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЛ рдпрд╛рдж рдХрд░рддрд╛ рд╣реИ, рдХреНрд▓рд╛рдЗрдВрдЯ рд╕реЗ рдХреНрд▓рд╛рдЗрдВрдЯ рдореЗрдВ рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рдиреЗ рдФрд░ рдХрдиреЗрдХреНрдЯреЗрдб рдХреНрд▓рд╛рдЗрдВрдЯ рдХреА рд╕реВрдЪреА (рдирдП рдЖрдЧрдорди рдХреЗ рд▓рд┐рдП) рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред

рдпрд╣рд╛рдВ рдореИрдВ рд╕рд░реНрд╡рд░ рдХреЛрдб рдирд╣реАрдВ рджреВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИред рд╣рдорд╛рд░реЗ рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдХрдореНрдпреБрдирд┐рдХреЗрд╢рди рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╣реЛрдиреЗ рджреЗрдВ:

 var observer = { // ... send: function(evt, data) { //       this._send(evt, data); }, on: function(evt, callback) { //    ("ICE"  "SDP",     ) // ... } // ... } 

рдХрдиреЗрдХреНрд╢рди рдмрдирд╛рдПрдВ


рдХрд▓реНрдкрдирд╛ рдХреАрдЬрд┐рдП рдХрд┐ рджреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реИрдВ - рдРрд▓рд┐рд╕ рдФрд░ рдмреЙрдмред рдмреЙрдм рдЙрд╕ рд╕рдордп рдЪреИрдЯ рдореЗрдВ рдЪрд▓рд╛ рдЧрдпрд╛ рдЬрдм рд╡рд╣рд╛рдВ рдХреЛрдИ рдирд╣реАрдВ рдерд╛ рдФрд░ рдПрд▓рд┐рд╕ рдПрдХ рдорд┐рдирдЯ рдмрд╛рдж рдЖрдпрд╛ рдФрд░ рд╕рд┐рдЧреНрдирд▓ рд╕рд░реНрд╡рд░ рд╕реЗ рдЙрд╕реЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдмреЙрдм рдСрдирд▓рд╛рдЗрди рдерд╛ рдФрд░ рдЙрд╕рдХрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣рд╛ рдерд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдРрд▓рд┐рд╕ рдмреЙрдм рдХреЛ рдПрдХ рдХрдиреЗрдХреНрд╢рди рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдЧрд╛, рдФрд░ рдмреЙрдм рдЙрд╕реЗ рдЬрд╡рд╛рдм рджреЗрдВрдЧреЗред

рдХрдиреЗрдХреНрд╢рди рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдРрд▓рд┐рд╕ рдПрдХ RTCPeerConnection рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддрд╛ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдХреЛ рдпрд╛рдж рд╣реИ, рд╣рдордиреЗ рдПрдХ рдХреНрд░реЙрд╕-рдмреНрд░рд╛рдЙрдЬрд╝рд░ _RTCPeerConnection рдХреЛ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдмрдирд╛рдпрд╛ рд╣реИ)ред рдирд┐рд░реНрдорд╛рддрд╛ рдХреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рджреЛ рддрд░реНрдХ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рдиреАрдЪреЗ рдЪрд░реНрдЪрд╛ рдХрд░реВрдВрдЧрд╛ред

 var pc, channel; var config = { iceServers: [{ url: !browser.mozilla ? "stun:stun.l.google.com:19302" : "stun:23.21.150.121" }] }; var constrains = { options: [{ DtlsSrtpKeyAgreement: true }, { RtpDataChannels: true }] }; function createPC(isOffer) { pc = new _RTCPeerConnection(config, constrains); //     pc.onicecandidate = function(evt) { if(evt.candidate) { //  ICE-         observer.send('ICE', evt.candidate); } }; pc.onconnection = function() { //      Firefox console.log('Connection established'); }; pc.onclosedconnection = function() { //   .  Chrome        console.log('Disconnected'); }; if(isOffer) { openOfferChannel(); createOffer(); } else { openAnswerChannel(); } } 

 //    createPC(true); 

рдЪреВрдВрдХрд┐ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдореЗрдВ рдХрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рджрд╛рддрд╛ NAT рдХреЗ рдкреАрдЫреЗ рд╣реИрдВ, WebRTC рдЗрд╕реЗ ( ICE , STUN , TURN ) рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдкрд╣рд▓рд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ STUN рдФрд░ / рдпрд╛ TURN рд╕рд░реНрд╡рд░ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЗ рд╕рд╛рде рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИред рдЖрдк рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЖрдк рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ рдЙрдард╛ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВрдиреЗ Google рд╕реЗ STUN рд╕рд░реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред рд╡реИрд╕реЗ, рдЕрдЧрд░ рдореБрдЭреЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╕рдордЭ рдореЗрдВ рдЖрдпрд╛, рддреЛ рдЖрдЬ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдореЗрдВ рдбреЛрдореЗрди STUN- рд╕рд░реНрд╡рд░ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП, рдЗрд╕рдореЗрдВ рджреВрд╕рд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЧрдИ рд╣реИред
рдмрд╛рдзрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╣реИ; рдХрдиреЗрдХреНрд╢рди рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдЗрд╕рдореЗрдВ рдкрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВред рдЖрдк рдпрд╣рд╛рдВ рдкрд░ DtlsSrtpKeyAgreement рд╡рд┐рдХрд▓реНрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ RtpDataChannels рд╡рд┐рдХрд▓реНрдк Chrome 25 (рдФрд░ рд╢рд╛рдпрдж рдХреБрдЫ рдЕрдиреНрдп рд╕рдВрд╕реНрдХрд░рдгреЛрдВ) рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд▓рдЧрддрд╛ рд╣реИ ред 28 рд╕рд╛рд▓ рдХреА рдЙрдореНрд░ рдореЗрдВ, рдореИрдВрдиреЗ рдЙрд╕рдХреЗ рдмрд┐рдирд╛ рдХрд╛рдо рдХрд┐рдпрд╛ред

рдХрдиреЗрдХреНрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдХреЛ рдПрдХ рд╕рд┐рдЧреНрдирд▓ рд╕рд░реНрд╡рд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдИрд╕реАрдИ рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдЙрдирдореЗрдВ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕, рдкрддрд╛ рдЖрджрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рд╣реЛрддрд╛ рд╣реИ)ред рдЬрдм рдкреНрд░рддреНрдпреЗрдХ рдЙрдореНрдореАрджрд╡рд╛рд░ рдкреНрд░рдХрдЯ рд╣реЛрддрд╛ рд╣реИ, рддреЛ pc.onicecandidate рдИрд╡реЗрдВрдЯ рдЖрдЧ рдЬрд╛рдПрдЧрд╛ (рдпрд╣ рд╕реНрдерд╛рдиреАрдп рд╕рддреНрд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╢реБрд░реВ рд╣реЛрдЧрд╛ рд╕реЗрдЯрд▓реЗрдХрд╕реНрдХреНрд░рд┐рдкреНрд╢рди рд╡рд┐рдзрд┐, рдЬреЛ рдиреАрдЪреЗ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреА)ред

рджреВрд╕рд░реЗ рдкреНрд░рддрд┐рднрд╛рдЧреА рд╕реЗ рдЙрдореНрдореАрджрд╡рд╛рд░ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реЛрдирд╛:

 observer.on('ICE', function(ice) { //   ICE- pc.addIceCandidate(new _RTCIceCandidate(ice)); }); 

рдЗрд╕рдХреЗ рдмрд╛рдж, рдРрд▓рд┐рд╕ рдПрдХ рдЪреИрдирд▓ рдмрдирд╛рддрд╛ рд╣реИред рдЗрд╕ рдЪреИрдирд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:

 function openOfferChannel() { //   тАУ  ,  - .    Chrome   UDP- (non-reliable),  Firefox тАУ  UDP,  TCP (reliable) channel = pc.createDataChannel('RTCDataChannel', browser.chrome ? {reliable: false} : {}); //  ,       binaryType  "blob",      Firefox (Chrome  ) if(browser.mozilla) channel.binaryType = 'blob'; setChannelEvents(); } function setChannelEvents() { channel.onopen = function() { console.log('Channel opened'); }; channel.onclose = function() { console.log('Channel closed'); }; channel.onerror = function(err) { console.log('Channel error:', err); }; channel.onmessage = function(e) { console.log('Incoming message:', e.data); }; } 

рдЕрдЧрд▓рд╛ рдХрджрдо, рдРрд▓рд┐рд╕ рдмреЙрдм рдХреЛ рдПрдХ "рдкреНрд░рд╕реНрддрд╛рд╡" (рд╡рд┐рднрд┐рдиреНрди рд╕реЗрд╡рд╛ рдЬрд╛рдирдХрд╛рд░реА, рдПрд╕рдбреАрдкреА рдХреЗ рд╕рд╛рде рд╕рддреНрд░ рдХрд╛ рд╡рд┐рд╡рд░рдг) рднреЗрдЬрддрд╛ рд╣реИ рдФрд░ рднреЗрдЬрддрд╛ рд╣реИред

 function createOffer() { pc.createOffer(function(offer) { pc.setLocalDescription(offer, function() { //       observer.send('SDP', offer); //        pc.onicecandidate }, function(err) { console.log('Failed to setLocalDescription():', err); }); }, function(err) { console.log('Failed to createOffer():', err); }); } 

рдЕрдм рдПрд▓рд┐рд╕ рд╕рд┐рдЧреНрдирд▓ рд╕рд░реНрд╡рд░ рд╕реЗ рдмреЙрдм рдХреЗ рд╕рддреНрд░ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд░рд╣реА рд╣реИред рдЬрдм рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ, setRemoteSDP рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

 function setRemoteSDP(sdp) { pc.setRemoteDescription(new _RTCSessionDescription(sdp), function() { if(pc.remoteDescription.type == 'offer') { //     createAnswer(); } }, function(err) { console.log('Failed to setRemoteDescription():', err); }); } observer.on('SDP', function(sdp) { if(!pc) { //  Offer    //    createPC(false); } setRemoteSDP(sdp); }); 

рдЗрд╕ рдмреАрдЪ, рдмреЙрдм рд╕рд┐рдЧреНрдирд▓ рд╕рд░реНрд╡рд░ рд╕реЗ рдРрд▓рд┐рд╕ рдХреЗ рд╕рддреНрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдЕрдкрдиреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдЖрд░рдЯреАрд╕реАрдкреАрдпрд░рдХрдиреЗрдХреНрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЪреИрдирд▓ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИ (рдЗрд╕реЗ createPC рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ)ред

 function openAnswerChannel() { pc.ondatachannel = function(e) { channel = e.channel; if(browser.mozilla) channel.binaryType = 'blob'; setChannelEvents(); }; } 

рдЕрдВрдд рдореЗрдВ, рдмреЙрдм рдРрд▓рд┐рд╕ рдХреЗ рд╕рддреНрд░ рдХреЛ рдмрдЪрд╛рддрд╛ рд╣реИ, рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдРрд▓рд┐рд╕ рдХреЛ рднреЗрдЬрддрд╛ рд╣реИред

 function createAnswer() { pc.createAnswer(function(offer) { pc.setLocalDescription(offer, function() { //       observer.send('SDP', offer); }, function(err) { console.log('Failed to setLocalDescription():', err); }); }, function(err) { console.log('Failed to createAnswer():', err); }); } 

рд╕рдВрджреЗрд╢ рд╕реЗрд╡рд╛


рджреЛрдиреЛрдВ рдкреНрд░рддрд┐рднрд╛рдЧрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕реЗрдЯRemoteDescription () рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдФрд░ ICE рдЙрдореНрдореАрджрд╡рд╛рд░реЛрдВ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдРрд▓рд┐рд╕ рдФрд░ рдмреЙрдм рдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдз рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, Channel.onopen рдЗрд╡реЗрдВрдЯ рдХреНрд░реЛрдо рдФрд░ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдореЗрдВ рдФрд░ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдореЗрдВ pc.onconnection рдХреЛ рдлрд╛рдпрд░ рдХрд░реЗрдЧрд╛ред

рдРрд▓рд┐рд╕ рдФрд░ рдмреЙрдм рдЕрдм рдЪреИрдирд▓.рд╕реЗрдВрдб () рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрджреЗрд╢реЛрдВ рдХрд╛ рдЖрджрд╛рди-рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 channel.send("Hi there!"); 

рдЬрдм рдХреЛрдИ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЪреИрдирд▓.рдСрдирдореЗрд╕реЗрдЬ рдЗрд╡реЗрдВрдЯ рдореЗрдВ рдЖрдЧ рд▓рдЧ рдЬрд╛рдПрдЧреАред

рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдкрд░рд┐рднрд╛рд╖рд╛;


рдЬрдм рдПрдХ рдЕрдиреНрдп рдкреНрд░рддрд┐рднрд╛рдЧреА рдХрдиреЗрдХреНрд╢рди рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдлрд╝рд╛рдпрд░рдлрд╝реЙрдХреНрд╕ рдореЗрдВ рджреЛ рдШрдЯрдирд╛рдУрдВ рдХреЛ рддреБрд░рдВрдд рдЯреНрд░рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: pc.onclosedconnection рдФрд░ channel.clcloseред
рд▓реЗрдХрд┐рди рдХреНрд░реЛрдо рдореЗрдВ рдХреБрдЫ рднреА рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдкреАрд╕реА рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЖрдЗрд╕рдХреЙрдиреНрдиреЗрд╕реНрдЯреЗрд╕реНрдЯреЗрдЯ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдореВрд▓реНрдп "рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ" рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ рд╣реИ (рдореЗрд░реА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдпрд╣ рддреБрд░рдВрдд рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдХреБрдЫ рд╕реЗрдХрдВрдб рдХреЗ рдмрд╛рдж рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ)ред рдЗрд╕рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рдЫреЛрдЯрд╛ рдмреИрд╕рд╛рдЦреА рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ рдЬрдм рддрдХ рдХрд┐ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдиреЗ рдЗрд╡реЗрдВрдЯ рдХреЙрд▓ рдХреЛ рдареАрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред

 if(browser.chrome) { setInterval(function() { if(pc.iceConnectionState == "disconnected") { console.log("Disconnected"); } }, 1000); } 

рд╡рд░реНрддрдорд╛рди рдореБрджреНрджреЗ



рдирд┐рд╖реНрдХрд░реНрд╖


рддрдХрдиреАрдХ рдореБрдЭреЗ рдмрд╣реБрдд рдЖрд╢рд╛рдЬрдирдХ рд▓рдЧрддреА рд╣реИ, рдФрд░ рдЕрдм рдЖрдк рдЗрд╕рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реАрдорд╛рдУрдВ рдХреЗ рд╕рд╛рдеред
рдФрд░ рдпрд╣рд╛рдВ рдПрдХ рд╕рд░рд▓ рдЪреИрдЯ рдХрд╛ рд▓рд┐рдВрдХ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕рдХреА рдирд┐рд░реНрдорд╛рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдиреЗ рдореБрдЭреЗ рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛ред рдореИрдВрдиреЗ рдЗрд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ WebRTC рдХреЗ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдФрд░ рд╕реАрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦрд╛ рдерд╛, рдФрд░ рдХреНрд░реЛрдо рдореЗрдВ рдпрд╣ ~ 1100 рдмрд╛рдЗрдЯреНрд╕ рд╕реЗ рдЕрдзрд┐рдХ рдирд╣реАрдВ рднреЗрдЬ рдкрд╛рдПрдЧрд╛ (рдореИрдВрдиреЗ рдмреНрд░реЗрдХрдбрд╛рдЙрди рдирд╣реАрдВ рдХрд┐рдпрд╛)ред

рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕реНрд░реЛрдд:

Source: https://habr.com/ru/post/In187270/


All Articles