Sinyal verme nedir?
İşaretleme, iletişimi koordine etme sürecidir. Bir WebRTC uygulamasının arama oluşturması için istemcilerinin aşağıdaki bilgileri paylaşması gerekir:
- İletişimi açmak veya kapatmak için kullanılan oturum denetimi mesajları
- Hata mesajları
- Codec'ler, codec ayarları, bant genişliği ve medya türleri gibi medya meta verileri
- Güvenli bağlantılar kurmak için kullanılan temel veriler
- Dış dünya tarafından görülen bir ana makinenin IP adresi ve bağlantı noktası gibi ağ verileri
Bu sinyal verme işlemi için istemcilerin mesajları birbirine iletmesi gerekir. Bu mekanizma, WebRTC API'leri tarafından uygulanmaz. Bu yöntemi kendiniz oluşturmanız gerekir. Bu makalenin ilerleyen bölümlerinde, sinyal hizmeti oluşturma yöntemlerini öğreneceksiniz. Ancak önce biraz bağlam bilgisine ihtiyacınız var.
İşaretleme neden WebRTC tarafından tanımlanmıyor?
Yinelenen öğelerin önüne geçmek ve yerleşik teknolojilerle uyumluluğu en üst düzeye çıkarmak için sinyalleme yöntemleri ve protokolleri WebRTC standartları tarafından belirtilmez. Bu yaklaşım, JavaScript Oturum Kurma Protokolü (JSEP) tarafından özetlenmiştir:
JSEP'in mimarisi, tarayıcının durumu kaydetmesi yani sinyal durumu makinesi olarak çalışması gerekmesini de önler. Örneğin, bir sayfa her yeniden yüklendiğinde sinyal verileri kaybolursa bu sorunlu olur. Bunun yerine, sinyal durumu bir sunucuya kaydedilebilir.
JSEP, yukarıda bahsedilen medya meta verilerinin teklif ve yanıt olarak eşleştirilmesini gerektirir. Teklifler ve yanıtlar, aşağıdaki gibi görünen Oturum Açıklama Protokolü (SDP) biçiminde iletilir:
v=0
o=- 7614219274584779017 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS
m=audio 1 RTP/SAVPF 111 103 104 0 8 107 106 105 13 126
c=IN IP4 0.0.0.0
a=rtcp:1 IN IP4 0.0.0.0
a=ice-ufrag:W2TGCZw2NZHuwlnf
a=ice-pwd:xdQEccP40E+P0L5qTyzDgfmW
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=mid:audio
a=rtcp-mux
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:9c1AHz27dZ9xPI91YNfSlI67/EMkjHHIHORiClQe
a=rtpmap:111 opus/48000/2
…
Tüm bu SDP karmaşıklığının ne anlama geldiğini öğrenmek ister misiniz? İnternet Mühendisliği Görev Gücü (IETF) örneklerine göz atın.
WebRTC'nin, teklifin veya yanıtın yerel ya da uzak açıklama olarak ayarlanmasından önce SDP metnindeki değerler düzenlenerek düzenlenebileceği şekilde tasarlandığını unutmayın. Örneğin, varsayılan codec'i ve bit hızını ayarlamak için appr.tc içindeki preferAudioCodec()
işlevi kullanılabilir. SDP'yi JavaScript ile değiştirmek biraz zordur ve WebRTC'nin gelecekteki sürümlerinde bunun yerine JSON'un kullanılması gerektiği konusunda tartışmalar vardır. Ancak SDP'yi kullanmaya devam etmenin bazı avantajları vardır.
RTCPeerConnection
API ve sinyal verme: Teklif, yanıt ve aday
RTCPeerConnection
, WebRTC uygulamaları tarafından eşler arasında bağlantı oluşturmak ve ses ile video iletişimi sağlamak için kullanılan API'dir.
Bu işlemi başlatmak için RTCPeerConnection
'ün iki görevi vardır:
- Çözünürlük ve codec özellikleri gibi yerel medya koşullarını belirleyin. Bu, teklif ve yanıt mekanizması için kullanılan meta verilerdir.
- Uygulamanın ana makinesi için adaylar olarak bilinen potansiyel ağ adreslerini alın.
Bu yerel veriler belirlendikten sonra uzak eşle bir sinyal mekanizması aracılığıyla değiştirilmelidir.
Alev'in Ece'yi aradığını varsayalım. Teklif/yanıt mekanizmasının tüm ayrıntılarını aşağıda bulabilirsiniz:
- Ayla bir
RTCPeerConnection
nesnesi oluşturur. - Alev,
RTCPeerConnection
createOffer()
yöntemiyle bir teklif (SDP oturum açıklaması) oluşturur. - Ayşe, teklifini
setLocalDescription()
'e iletir. - Ayla, teklifi dize haline getirir ve bir sinyal mekanizması kullanarak teklifi Ece'ye gönderir.
- Ece,
RTCPeerConnection
'nin Alice'in kurulumundan haberdar olması için Alice'in teklifinisetRemoteDescription()
'e bildirir. - Ece,
createAnswer()
'ü çağırır ve bunun için başarı geri çağırma işlevine yerel bir oturum açıklaması (Ece'nin yanıtı) iletilir. - Eve,
setLocalDescription()
işlevini çağırarak cevabını yerel açıklama olarak ayarlar. - Ardından Eve, dize haline getirilmiş yanıtını Alice'e göndermek için sinyal mekanizmasını kullanır.
- Ayşe,
setRemoteDescription()
kullanarak Ece'nin yanıtını uzak oturum açıklaması olarak ayarlar.
Ayla ve Ece'nin de ağ bilgilerini paylaşması gerekir. "Aday bulma" ifadesi, ICE çerçevesini kullanarak ağ arayüzlerini ve bağlantı noktalarını bulma işlemini ifade eder.
- Alice,
onicecandidate
işleyicisi olan birRTCPeerConnection
nesnesi oluşturur. - Ağ adayları kullanılabilir hale geldiğinde işleyici çağrılır.
- İşleyicide Alice, dize haline getirilmiş aday verileri sinyal kanalıyla Eve'e gönderir.
- Ece, Aydan bir aday mesajı aldığında, adayı uzak eş tanımına eklemek için
addIceCandidate()
işlevini çağırır.
JSEP, ICE adayını kademeli olarak gönderme özelliğini destekler. Bu özellik, arayanın ilk tekliften sonra aranan tarafa kademeli olarak aday sağlamasına ve aranan tarafın tüm adayların gelmesini beklemeden aramada işlem yapmaya başlamasına ve bağlantı kurmasına olanak tanır.
Sinyal verme için WebRTC kodlama
Aşağıdaki kod snippet'i, sinyal verme sürecinin tamamını özetleyen bir W3C kod örneğidir. Kodda, SignalingChannel
adlı bir sinyal mekanizmasının varlığı varsayılır. Sinyal verme daha sonra ayrıntılı olarak ele alınacaktır.
// 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);
}
};
// After 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);
}
};
Teklif/yanıt ve aday değişimi işlemlerini çalışırken görmek için simpl.info RTCPeerConnection sayfasına bakın ve tek sayfalık bir görüntülü sohbet örneği için konsol günlüğüne göz atın. Daha fazla bilgi edinmek istiyorsanız Google Chrome'daki about://webrtc-internals sayfasından veya Opera'daki opera://webrtc-internals sayfasından WebRTC sinyal ve istatistiklerinin tam dökümünü indirin.
Eş bulma
Bu, "Nasıl konuşabileceğim birini bulabilirim?" sorusunun şık bir ifadesidir.
Telefon aramaları için telefon numaraları ve dizinleriniz vardır. Online görüntülü sohbet ve mesajlaşma için kimlik ve varlık yönetimi sistemlerine ve kullanıcıların oturum başlatabileceği bir yola ihtiyacınız vardır. WebRTC uygulamalarının, istemcilerin bir görüşme başlatmak veya görüşmeye katılmak istediklerini birbirlerine bildirmelerine olanak tanıyan bir yönteme ihtiyacı vardır.
Eş bulma mekanizmaları WebRTC tarafından tanımlanmaz ve buradaki seçeneklere giremezsiniz. Bu işlem, bir URL'yi e-postayla veya mesajla göndermek kadar basit olabilir. Talky, tawk.to ve Browser Meeting gibi görüntülü sohbet uygulamalarında, özel bir bağlantı paylaşarak kullanıcıları görüşmeye davet edebilirsiniz. Geliştirici Chris Ball, WebRTC görüşmesi katılımcılarının istedikleri mesajlaşma hizmeti (ör. sohbet, e-posta veya posta güvercini) üzerinden meta veri alışverişi yapmasına olanak tanıyan ilgi çekici bir sunucusuz-webrtc denemesi yaptı.
Sinyalleme hizmeti nasıl oluşturabilirsiniz?
Sinyal protokollerinin ve mekanizmalarının WebRTC standartları tarafından tanımlanmadığını tekrar belirtmek isteriz. Hangisini seçerseniz seçin, istemciler arasında sinyal mesajları ve uygulama verileri alışverişinde bulunmak için bir aracı sunucuya ihtiyacınız vardır. Maalesef bir web uygulaması, internete "Arkadaşıma bağla beni" diye bağıramaz.
Neyse ki sinyal mesajları küçüktür ve çoğunlukla aramanın başında paylaşılır. appr.tc ile yapılan görüntülü sohbet oturumu testinde, sinyal hizmetinde toplam 30-45 mesaj işlendi. Tüm mesajların toplam boyutu yaklaşık 10 KB'tı.
WebRTC sinyal hizmetleri, bant genişliği açısından nispeten az kaynak gerektirmesinin yanı sıra yalnızca mesajları iletmesi ve hangi istemcilerin bağlı olduğu gibi az miktarda oturum durumu verisi tutması gerektiğinden çok fazla işlem gücü veya bellek tüketmez.
Mesajları sunucudan istemciye aktarma
Sinyal gönderme için bir mesaj hizmetinin iki yönlü olması gerekir: istemciden sunucuya ve sunucudan istemciye. İki yönlü iletişim, HTTP istemci/sunucu istek/yanıt modeline aykırıdır ancak web sunucusunda çalışan bir hizmetten tarayıcıda çalışan bir web uygulamasına veri göndermek için yıllar içinde uzun anket gibi çeşitli yöntemler geliştirilmiştir.
Daha yakın zamanda EventSource
API yaygın olarak uygulanmaya başlandı. Bu, sunucu tarafından gönderilen etkinlikleri (HTTP üzerinden bir web sunucusundan tarayıcı istemcisine gönderilen veriler) etkinleştirir. EventSource
tek yönlü mesajlaşma için tasarlanmıştır ancak sinyal mesajları alışverişi için bir hizmet oluşturmak üzere XHR ile birlikte kullanılabilir. Sinyal hizmetinde, arayandan gelen ve XHR isteğiyle gönderilen bir mesaj, EventSource
üzerinden aranan kullanıcıya iletilir.
WebSocket, tam çift yönlü istemci-sunucu iletişimi (aynı anda her iki yönde de iletilebilen mesajlar) için tasarlanmış daha doğal bir çözümdür. Saf WebSocket veya sunucu tarafından gönderilen etkinliklerle (EventSource
) oluşturulan bir sinyalleme hizmetinin avantajlarından biri, bu API'lerin arka uçlarının PHP, Python ve Ruby gibi diller için çoğu web barındırma paketinde ortak olan çeşitli web çerçevelerinde uygulanabilmesidir.
Opera Mini dışındaki tüm modern tarayıcılar WebSocket'i destekler. Daha da önemlisi, WebRTC'yi destekleyen tüm tarayıcılar hem masaüstünde hem de mobil cihazlarda WebSocket'i destekler. İletilerin şifrelenmeden ele geçirilememesi ve proxy geçişiyle ilgili sorunların azaltılması için tüm bağlantılarda TLS kullanılmalıdır. (WebSocket ve proxy geçişi hakkında daha fazla bilgi için Ilya Grigorik'in Yüksek Performanslı Tarayıcı Ağı kitabındaki WebRTC bölümüne bakın.)
WebRTC istemcilerinin Ajax aracılığıyla bir mesajlaşma sunucusunu tekrar tekrar sorgulayarak sinyali işlemesini sağlamak da mümkündür ancak bu, özellikle mobil cihazlar için sorun teşkil eden çok sayıda gereksiz ağ isteği gönderir. Bir oturum kurulduktan sonra bile, diğer eşler tarafından değişiklik yapılması veya oturumun sonlandırılması durumunda eşlerin sinyal mesajları için anket yapması gerekir. WebRTC Kitabı uygulama örneği, anket aralığı için bazı optimizasyonlarla bu seçeneği kullanır.
Ölçek sinyali
Bir sinyalleşme hizmeti, istemci başına nispeten az bant genişliği ve CPU tüketir. Ancak popüler bir uygulamanın sinyalleşme sunucularının, yüksek eşzamanlılık düzeylerinde farklı konumlardan gelen çok sayıda mesajı işlemesi gerekebilir. Çok fazla trafik alan WebRTC uygulamalarının, önemli miktarda yükü kaldırabilecek sinyal sunucularına ihtiyacı vardır. Burada ayrıntılara girmiyorsunuz ancak yüksek hacimli, yüksek performanslı mesajlaşma için aşağıdakiler de dahil olmak üzere çeşitli seçenekler vardır:
Genişletilebilir Mesajlaşma ve Mevcutluk Protokolü (XMPP), orijinal olarak Jabber olarak bilinir. Anlık mesajlaşma için geliştirilmiş ve sinyal göndermek için kullanılabilen bir protokoldür (ejabberd ve Openfire sunucu uygulamaları arasındadır. Strophe.js gibi JavaScript istemcileri, iki yönlü aktarımı taklit etmek için BOSH'u kullanır ancak çeşitli nedenlerden dolayı BOSH, WebSocket kadar verimli olmayabilir ve aynı nedenlerden dolayı iyi ölçeklenmeyebilir.) (Jingle, ses ve videoyu etkinleştirmek için kullanılan bir XMPP uzantısıdır. WebRTC projesi, Jingle'in C++ uygulaması olan libjingle kitaplığındaki ağ ve aktarım bileşenlerini kullanır.)
ZeroMQ (TokBox'un Rumour hizmeti için kullandığı) ve OpenMQ (NullMQ, WebSocket üzerinden STOMP protokolünü kullanarak ZeroMQ kavramlarını web platformlarına uygular.) gibi açık kaynak kitaplıklar
Pusher, Kaazing ve PubNub gibi WebSocket kullanan ticari bulut mesajlaşma platformları (ancak uzun süreli ankete geçebilirler) (PubNub'un WebRTC için API'si de vardır.)
vLine gibi ticari WebRTC platformları
(Geliştirici Phil Leggetter'ın Gerçek Zamanlı Web Teknolojileri Rehberi, mesajlaşma hizmetlerinin ve kitaplıklarının kapsamlı bir listesini sunar.)
Node'da Socket.io ile sinyal hizmeti oluşturma
Aşağıda, Node üzerinde Socket.io ile oluşturulmuş bir sinyal hizmeti kullanan basit bir web uygulamasının kodu verilmiştir. Socket.io'nun tasarımı, mesaj alışverişi yapacak bir hizmet oluşturmayı kolaylaştırır. Socket.io, yerleşik oda konsepti nedeniyle özellikle WebRTC sinyalizasyonuna uygundur. Bu örnek, üretim sınıfı bir sinyalleme hizmeti olarak ölçeklendirilmek üzere tasarlanmamıştır ancak nispeten az sayıda kullanıcı için anlaşılması kolaydır.
Socket.io, yedeklerle birlikte WebSocket kullanır: AJAX uzun anketi, AJAX çok parçalı aktarımı, Forever Iframe ve JSONP anketi. Çeşitli arka uçlara taşınmıştır ancak belki de en çok bu örnekte kullanılan Node sürümü ile bilinir.
Bu örnekte WebRTC yoktur. Yalnızca bir web uygulamasına sinyal göndermenin nasıl yapıldığını göstermek için tasarlanmıştır. İstemciler bir odaya katılıp mesaj alışverişi yaparken neler olduğunu görmek için konsol günlüğünü görüntüleyin. Bu WebRTC codelab'inde, bu kodun eksiksiz bir WebRTC görüntülü sohbet uygulamasına nasıl entegre edileceğine dair adım adım talimatlar verilmiştir.
index.html
müşterisi:
<!DOCTYPE html>
<html>
<head>
<title>WebRTC client</title>
</head>
<body>
<script src='/socket.io/socket.io.js'></script>
<script src='js/main.js'></script>
</body>
</html>
İstemcide referans verilen main.js
JavaScript dosyası aşağıda verilmiştir:
const isInitiator;
room = prompt('Enter room name:');
const socket = io.connect();
if (room !== '') {
console.log('Joining room ' + room);
socket.emit('create or join', room);
}
socket.on('full', (room) => {
console.log('Room ' + room + ' is full');
});
socket.on('empty', (room) => {
isInitiator = true;
console.log('Room ' + room + ' is empty');
});
socket.on('join', (room) => {
console.log('Making request to join room ' + room);
console.log('You are the initiator!');
});
socket.on('log', (array) => {
console.log.apply(console, array);
});
Sunucu uygulamasının tamamı aşağıda verilmiştir:
const static = require('node-static');
const http = require('http');
const file = new(static.Server)();
const app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2013);
const io = require('socket.io').listen(app);
io.sockets.on('connection', (socket) => {
// Convenience function to log server messages to the client
function log(){
const array = ['>>> Message from server: '];
for (const i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', (message) => {
log('Got message:', message);
// For a real app, would be room only (not broadcast)
socket.broadcast.emit('message', message);
});
socket.on('create or join', (room) => {
const numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room ' + room);
if (numClients === 0){
socket.join(room);
socket.emit('created', room);
} else if (numClients === 1) {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
} else { // max two clients
socket.emit('full', room);
}
socket.emit('emit(): client ' + socket.id +
' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id +
' joined room ' + room);
});
});
(Bunun için node-static hakkında bilgi edinmeniz gerekmez. Bu örnekte kullanıldığı için.)
Bu uygulamayı localhost'ta çalıştırmak için Node, Socket.IO ve node-static'in yüklü olması gerekir. Node'u Node.js'den indirebilirsiniz (kurulum basit ve hızlıdır). Socket.IO ve node-static'i yüklemek için uygulama dizininizdeki bir terminalden Node Package Manager'ı çalıştırın:
npm install socket.io
npm install node-static
Sunucuyu başlatmak için uygulama dizininizdeki bir terminalden aşağıdaki komutu çalıştırın:
node server.js
Tarayıcınızda localhost:2013
'ü açın. Herhangi bir tarayıcıda yeni bir sekme veya pencere açın ve localhost:2013
'ü tekrar açın. Neler olduğunu görmek için konsolu kontrol edin. Chrome ve Opera'da, Ctrl+Shift+J
(veya Mac'te Command+Option+J
) tuşlarını kullanarak Google Chrome Geliştirici Araçları üzerinden konsola erişebilirsiniz.
İşaretleme için hangi yaklaşımı seçerseniz seçin, arka uç ve istemci uygulamanızın en azından bu örnektekilere benzer hizmetler sağlaması gerekir.
Sinyallerle ilgili dikkat edilmesi gereken noktalar
RTCPeerConnection
,setLocalDescription()
çağrılana kadar aday toplamaya başlamaz. Bu, JSEP IETF taslağında zorunlu kılınmıştır.- Trickle ICE'ten yararlanın. Adaylar gelir gelmez
addIceCandidate()
numaralı telefonu arayın.
Hazır sinyal sunucuları
Kendi sunucunuzu oluşturmak istemiyorsanız önceki örnekte olduğu gibi Socket.IO kullanan ve WebRTC istemci JavaScript kitaplıklarıyla entegre edilmiş çeşitli WebRTC sinyal sunucuları mevcuttur:
- webRTC.io, WebRTC için ilk soyutlama kitaplıklarından biridir.
- Signalmaster, SimpleWebRTC JavaScript istemci kitaplığıyla kullanılmak üzere oluşturulmuş bir sinyal sunucusudur.
Hiçbir kod yazmak istemiyorsanız vLine, OpenTok ve Asterisk gibi şirketlerden eksiksiz ticari WebRTC platformları satın alabilirsiniz.
Ericsson, WebRTC'nin ilk günlerinde Apache'te PHP kullanarak bir sinyal sunucusu oluşturdu. Bu yöntem artık biraz eski olsa da benzer bir şey yapmayı düşünüyorsanız koda göz atmanızda fayda var.
Sinyal güvenliği
"Güvenlik, hiçbir şeyin olmaması sanatıdır."
Salman Rushdie
Tüm WebRTC bileşenleri için şifreleme zorunludur.
Ancak sinyal mekanizmaları WebRTC standartları tarafından tanımlanmadığından, sinyalleri güvenli hale getirmek size bağlıdır. Bir saldırgan, sinyalleri ele geçirmeyi başarırsa oturumları durdurabilir, bağlantıları yönlendirebilir ve içerik kaydedebilir, değiştirebilir veya ekleyebilir.
Sinyallerin güvenliğini sağlamanın en önemli faktörü, mesajların şifrelenmeden ele geçirilmesini önleyen güvenli protokoller (ör. HTTPS ve WSS (TLS)) kullanmaktır. Ayrıca, sinyal mesajlarını aynı sinyal sunucusunu kullanan diğer arayanlar tarafından erişilebilecek şekilde yayınlamamaya dikkat edin.
İşaretleme işleminden sonra: NAT'ler ve güvenlik duvarlarıyla başa çıkmak için ICE'yi kullanın
WebRTC uygulamaları, meta veri sinyali için bir aracı sunucu kullanır ancak oturum kurulduktan sonra gerçek medya ve veri akışı için RTCPeerConnection
istemcileri doğrudan veya eşler arası olarak bağlamaya çalışır.
Daha basit bir dünyada her WebRTC uç noktasının, doğrudan iletişim kurmak için diğer eşlerle paylaşabileceği benzersiz bir adresi olurdu.
Gerçekte, çoğu cihaz bir veya daha fazla NAT katmanının arkasındadır, bazılarında belirli bağlantı noktalarını ve protokolleri engelleyen antivirüs yazılımları bulunur ve çoğu proxy'lerin ve kurumsal güvenlik duvarlarının arkasındadır. Güvenlik duvarı ve NAT, aslında ev kablosuz yönlendiricisi gibi aynı cihaz tarafından uygulanabilir.
WebRTC uygulamaları, gerçek dünya ağlarının karmaşıklığını aşmak için ICE çerçevesini kullanabilir. Bunun gerçekleşmesi için uygulamanızın, bu makalede açıklandığı gibi ICE sunucu URL'lerini RTCPeerConnection
adresine iletmesi gerekir.
ICE, eşleri bağlamak için en iyi yolu bulmaya çalışır. Tüm olasılıkları paralel olarak dener ve işe yarayan en verimli seçeneği belirler. ICE, ilk olarak cihazın işletim sisteminden ve ağ kartından alınan ana makine adresini kullanarak bağlantı kurmaya çalışır. Bu işlem başarısız olursa (NAT'lerin arkasındaki cihazlar için başarısız olur) ICE, STUN sunucusu kullanarak harici bir adres alır ve bu işlem de başarısız olursa trafik bir TURN geçiş sunucusu üzerinden yönlendirilir.
Diğer bir deyişle, harici bir ağ adresi almak için STUN sunucusu, doğrudan (eşler arası) bağlantı başarısız olursa TURN sunucuları kullanılır.
Her TURN sunucusu STUN'u destekler. TURN sunucusu, ek yerleşik aktarma işlevine sahip bir STUN sunucusudur. ICE, NAT kurulumlarının karmaşıklığıyla da başa çıkabilir. Gerçekte, NAT deliği açma işlemi için herkese açık bir IP:port adresinin yanı sıra daha fazlası gerekebilir.
STUN ve/veya TURN sunucularının URL'leri (isteğe bağlı olarak) RTCPeerConnection
yapıcısının ilk bağımsız değişkeni olan iceServers
yapılandırma nesnesinde bir WebRTC uygulaması tarafından belirtilir. appr.tc için bu değer şu şekilde görünür:
{
'iceServers': [
{
'urls': 'stun:stun.l.google.com:19302'
},
{
'urls': 'turn:192.158.29.39:3478?transport=udp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
},
{
'urls': 'turn:192.158.29.39:3478?transport=tcp',
'credential': 'JZEOEt2V3Qb0y27GRntt2u2PAYA=',
'username': '28224511:1379330808'
}
]
}
RTCPeerConnection
bu bilgilere sahip olduğunda ICE'nin sihirli işlevi otomatik olarak gerçekleşir. RTCPeerConnection
, eşler arasında en iyi yolu belirlemek için ICE çerçevesini kullanır ve gerektiğinde STUN ve TURN sunucularıyla çalışır.
STUN
NAT'ler, cihaza özel yerel bir ağda kullanılacak bir IP adresi sağlar ancak bu adres harici olarak kullanılamaz. Herkese açık bir adres olmadan WebRTC eşlerinin iletişim kurması mümkün değildir. WebRTC, bu sorunun üstesinden gelmek için STUN'u kullanır.
STUN sunucuları herkese açık internette bulunur ve tek bir basit görevi vardır: Gelen bir isteğin (NAT arkasında çalışan bir uygulamadan) IP:port adresini kontrol etmek ve bu adresi yanıt olarak geri göndermek. Diğer bir deyişle, uygulama IP:portunu herkese açık bir perspektiften keşfetmek için bir STUN sunucusu kullanır. Bu işlem, bir WebRTC eşlemenin herkese açık bir adres almasını ve ardından doğrudan bağlantı oluşturmak için bir sinyal mekanizması aracılığıyla başka bir eşle paylaşmasını sağlar. (Uygulamada farklı NAT'ler farklı şekillerde çalışır ve birden fazla NAT katmanı olabilir ancak temel prensip aynıdır.)
STUN sunucularının çok fazla işlem yapması veya çok fazla şey hatırlaması gerekmez. Bu nedenle, nispeten düşük özellikli STUN sunucuları çok sayıda isteği işleyebilir.
WebRTC çağrılarının çoğu STUN kullanarak başarılı bir şekilde bağlantı kurar (Webrtcstats.com'a göre% 86). Ancak bu oran, güvenlik duvarlarının ve karmaşık NAT yapılandırmalarının arkasındaki eşler arasındaki çağrılarda daha düşük olabilir.
TURN
RTCPeerConnection
, UDP üzerinden eşler arasında doğrudan iletişim kurmaya çalışır. Bu yöntem başarısız olursa RTCPeerConnection
TCP'ye başvurur. Bu işlem başarısız olursa TURN sunucuları, uç noktalar arasında veri aktararak yedek olarak kullanılabilir.
TURN'in sinyal verileri değil, eşler arasında ses, görüntü ve veri aktarımı için kullanıldığını tekrar belirtmek isteriz.
TURN sunucularının herkese açık adresleri vardır. Bu nedenle, eşler güvenlik duvarları veya proxy'lerin arkasında olsa bile eşler tarafından bunlarla iletişim kurulabilir. TURN sunucularının görevi, kavramsal olarak basittir: bir yayını aktarmaktır. Ancak STUN sunucularının aksine, doğal olarak çok fazla bant genişliği tüketirler. Diğer bir deyişle, TURN sunucularının daha güçlü olması gerekir.
Bu şema, TURN'in işleyişini gösterir. Saf STUN başarılı olmadıysa her eş, TURN sunucusu kullanmaya başlar.
STUN ve TURN sunucularını dağıtma
Google, test için appr.tc tarafından kullanılan stun.l.google.com:19302 adresindeki herkese açık bir STUN sunucusu çalıştırır. Üretim STUN/TURN hizmeti için rfc5766-turn-server öğesini kullanın. STUN ve TURN sunucularının kaynak kodunu GitHub'da bulabilirsiniz. Burada, sunucu kurulumuyla ilgili çeşitli bilgi kaynaklarının bağlantılarını da bulabilirsiniz. Amazon Web Services için sanal makine resmi de kullanılabilir.
Alternatif bir TURN sunucusu, kaynak kod olarak ve AWS için de kullanılabilir. Compute Engine'de geri ödemeyi ayarlamayla ilgili talimatlar aşağıda verilmiştir.
- tcp=443, udp/tcp=3478 için gerektiği şekilde güvenlik duvarını açın.
- Her genel IP için bir tane olmak üzere dört örnek oluşturun. Standart Ubuntu 12.06 resmi.
- Yerel güvenlik duvarı yapılandırmasını ayarlayın (HERHANGİ bir kaynaktan HERHANGİ bir bağlantıya izin verin).
- Yükleme araçları:
shell sudo apt-get install make sudo apt-get install gcc
- creytiv.com/re.html adresinden libre'yi yükleyin.
- creytiv.com/restund.html adresinden geri ödemeyi alın ve paketini açın./
wget
hancke.name/restund-auth.patch adresinden indirin vepatch -p1 < restund-auth.patch
ile uygulayın.make
çalıştırın,sudo make install
için ücretsiz ve geri ödeme.restund.conf
dosyasını ihtiyaçlarınıza göre uyarlayın (IP adreslerini değiştirin ve aynı paylaşılan gizli anahtarı içerdiğinden emin olun) ve/etc
dosyasına kopyalayın.restund/etc/restund
dosyasını/etc/init.d/
klasörüne kopyalayın.- Geri ödemeyi yapılandırın:
LD_LIBRARY_PATH
değerini ayarlayın.restund.conf
dosyasını/etc/restund.conf
klasörüne kopyalayın.- Doğru 10'u kullanmak için
restund.conf
öğesini ayarlayın. IP adresi.
- Geri ödeme yapma
- Uzaktan makineden durma istemcisini kullanarak test edin:
./client IP:port
Bire bir görüşmelerin ötesinde: Çok taraflı WebRTC
Justin Uberti'nin TURN hizmetlerine erişim için REST API ile ilgili önerdiği IETF standardına da göz atabilirsiniz.
Medya akışının basit bir bire bir görüşmenin ötesine geçen kullanım alanlarını hayal etmek kolaydır. Örneğin, bir grup iş arkadaşı arasında yapılan görüntülü konferanslar veya yüzlerce ya da milyonlarca izleyicinin olduğu herkese açık etkinlikler.
Bir WebRTC uygulaması, her uç noktanın bir ağ yapılandırmasında diğer tüm uç noktalara bağlanması için birden fazla RTCPeerConnection kullanabilir. talky.io gibi uygulamalar bu yaklaşımı benimser ve bu yaklaşım, az sayıda akran için oldukça iyi çalışır. Bunun ötesinde, özellikle mobil istemciler için işleme ve bant genişliği tüketimi aşırı hale gelir.
Alternatif olarak, bir WebRTC uygulaması, yıldız yapılandırmasında yayınları diğer tüm uç noktalara dağıtmak için bir uç nokta seçebilir. Bir sunucuda WebRTC uç noktası çalıştırıp kendi yeniden dağıtım mekanizmanızı oluşturmanız da mümkündür (webrtc.org tarafından bir örnek istemci uygulaması sağlanır).
Chrome 31 ve Opera 18'den beri, bir RTCPeerConnection
'dan alınan MediaStream
, başka bir RTCPeerConnection
için giriş olarak kullanılabilir. Bu, bir web uygulamasının hangi diğer eşe bağlanacağını seçerek çağrı yönlendirmeyi ele almasını sağladığından daha esnek mimariler sunabilir. Bu işlemin nasıl çalıştığını görmek için WebRTC örnekleri Eş bağlantı aktarımı ve WebRTC örnekleri Birden fazla eş bağlantısı başlıklı makaleleri inceleyin.
Çoklu Nokta Kontrol Ünitesi
Çok sayıda uç nokta için daha iyi bir seçenek, çok noktalı kontrol birimi (MCU) kullanmaktır. Bu, çok sayıda katılımcı arasında medya dağıtmak için köprü görevi gören bir sunucudur. MCU'lar, görüntülü konferanslarda farklı çözünürlükler, codec'ler ve kare hızlarıyla başa çıkabilir, kod dönüştürme yapabilir, seçmeli yayın yönlendirmesi yapabilir ve ses ile videoyu karıştırabilir veya kaydedebilir. Çoklu katılımlı görüşmelerde, özellikle birden fazla video girişinin nasıl gösterileceği ve birden fazla kaynaktan gelen seslerin nasıl karıştırılacağı gibi çeşitli konular dikkate alınmalıdır. vLine gibi bulut platformları da trafik yönlendirmeyi optimize etmeye çalışır.
MCU donanım paketini satın alabilir veya kendiniz oluşturabilirsiniz.
Birkaç açık kaynak MCU yazılımı seçeneği mevcuttur. Örneğin, Licode (eski adıyla Lynckia), WebRTC için açık kaynak bir MCU üretir. OpenTok'ta Mantis bulunur.
Tarayıcılar dışında: VoIP, telefonlar ve mesajlaşma
WebRTC'nin standartlaştırılmış yapısı, tarayıcıda çalışan bir WebRTC uygulaması ile telefon veya görüntülü konferans sistemi gibi başka bir iletişim platformunda çalışan bir cihaz veya platform arasında iletişim kurulmasını sağlar.
SIP, VoIP ve video konferans sistemleri tarafından kullanılan bir sinyal protokolüdür. WebRTC web uygulaması ile SIP istemcisi (ör. görüntülü konferans sistemi) arasında iletişimi etkinleştirmek için WebRTC'nin, sinyalleri yönlendirmek üzere bir proxy sunucusuna ihtiyacı vardır. İşaretleme, ağ geçidi üzerinden akmalıdır ancak iletişim kurulduktan sonra SRTP trafiği (video ve ses) doğrudan eşler arasında akabilir.
Sabit Telefon Şebekesi (PSTN), tüm "eski tip" analog telefonların devresel anahtarlama ağıdır. WebRTC web uygulamaları ile telefonlar arasındaki aramalarda trafik bir PSTN ağ geçidinden geçmelidir. Benzer şekilde, WebRTC web uygulamalarının anlık mesajlaşma istemcileri gibi Jingle uç noktalarıyla iletişim kurması için bir aracı XMPP sunucusuna ihtiyacı vardır. Jingle, Google tarafından mesajlaşma hizmetlerinde ses ve görüntülü görüşmeyi etkinleştirmek için XMPP'nin bir uzantısı olarak geliştirilmiştir. Mevcut WebRTC uygulamaları, başlangıçta Talk için geliştirilen Jingle uygulaması olan C++ libjingle kitaplığını temel alır.
WebRTC'nin dış dünyayla iletişim kurma özelliğinden birçok uygulama, kitaplık ve platform yararlanır:
- sipML5: açık kaynak JavaScript SIP istemcisi
- jsSIP: JavaScript SIP kitaplığı
- Phono: eklenti olarak oluşturulmuş açık kaynak JavaScript telefon API'si
- Zingaya: Yerleştirilebilir telefon widget'ı
- Twilio: sesli iletişim ve mesajlaşma
- Uberconference: konferans görüşmesi
sipML5 geliştiricileri, webrtc2sip ağ geçidini de oluşturdu. Tethr ve Tropo, WebRTC aracılığıyla özellikli telefonlar ile bilgisayarlar arasında iletişimi sağlamak için OpenBTS hücresi kullanarak "avuç içi afet iletişimi çerçevesi" gösterdi. Bu, operatör olmadan telefon iletişimidir.
Daha fazla bilgi
WebRTC codelab'inde, Node'da çalışan bir Socket.io sinyalleme hizmeti kullanarak video ve metin sohbet uygulaması oluşturmayla ilgili adım adım talimatlar sağlanmaktadır.
WebRTC teknoloji sorumlusu Justin Uberti'nin 2013'teki Google I/O WebRTC sunumu
Chris Wilson'un SFHTML5 sunumu - WebRTC Uygulamalarına Giriş
350 sayfalık WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web (WebRTC: HTML5 Gerçek Zamanlı Web'in API'leri ve RTCWEB Protokolleri) adlı kitapta veri ve sinyal yolları hakkında birçok ayrıntı sağlanmakta ve çok sayıda ayrıntılı ağ topolojisi şeması bulunmaktadır.
WebRTC ve İşaretleme: İki Yıl Bize Neler Öğretti? - İşaretleme özelliğinin spesifikasyondan çıkarılmasının neden iyi bir fikir olduğuyla ilgili TokBox blog yayını
Ben Strong'un WebRTC Uygulamaları Geliştirme İçin Pratik Kılavuz adlı makalesinde WebRTC topolojileri ve altyapısı hakkında birçok bilgi verilmektedir.
Ilya Grigorik'in Yüksek Performanslı Tarayıcı Ağları kitabındaki WebRTC bölümü, WebRTC mimarisi, kullanım alanları ve performansı hakkında ayrıntılı bilgi içeriyor.