Yayınlanma tarihi: 4 Kasım 2013
WebRTC, eşler arası iletişimi sağlar. İstemcilerin meta veri alışverişi yapabilmesi ve sinyalizasyon adı verilen bir süreç aracılığıyla iletişimi koordine edebilmesi için sunucular gerekir. Sunucular, istemcilerin ağ adresi çeviricileri (NAT'ler) ve güvenlik duvarlarıyla başa çıkmasına da yardımcı olur.
Bu bölümde, sinyal hizmeti oluşturmayı ve STUN ile TURN sunucularıyla gerçek dünyadaki bağlantı sorunlarını çözmeyi öğreneceksiniz. Ayrıca WebRTC uygulamalarının çok taraflı aramaları nasıl yönetebileceğini ve VoIP ve PSTN (telefon olarak da bilinir) gibi hizmetlerle nasıl etkileşim kurabileceğini de öğreneceksiniz.
Sinyal verme nedir?
Sinyalleşme, iletişimi koordine etme sürecidir. Bir WebRTC uygulamasının arama yapabilmesi için istemcilerinin aşağıdaki bilgileri paylaşması gerekir:
- İletişimi açmak veya kapatmak için kullanılan oturum kontrolü 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 anahtar veriler
- Dış dünya tarafından görüldüğü şekliyle bir ana makinenin IP adresi ve bağlantı noktası gibi ağ verileri
Bu sinyalizasyon sürecinde, istemcilerin mesajları ileri geri iletmesi için bir yöntem gerekir. Bu mekanizma, WebRTC API'leri tarafından uygulanmaz. Bunun yerine, kendiniz oluşturmanız gerekir.
Sinyal alışverişi neden WebRTC tarafından tanımlanmıyor?
WebRTC standartları, fazlalığı önlemek ve mevcut teknolojilerle uyumluluğu en üst düzeye çıkarmak için sinyal yöntemlerini ve protokollerini belirtmez. Bu yaklaşım, JavaScript Session Establishment Protocol (JSEP) tarafından açıklanmıştır:
JSEP'in mimarisi, tarayıcının durumu kaydetmesini, yani bir sinyal durum makinesi olarak çalışmasını da önler. Örneğin, sayfa her yeniden yüklendiğinde sinyal verileri kaybolursa bu durum sorun yaratır. Bunun yerine, sinyal durumu bir sunucuya kaydedilebilir.
JSEP, eşler arasında medya meta verileri olan teklif ve yanıt alışverişi yapılmasını gerektirir. Teklifler ve yanıtlar, Oturum Tanımlama Protokolü (SDP) biçiminde iletilir. Bu biçim aşağıdaki gibidir:
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 jargonunun gerçekte ne anlama geldiğini öğrenmek ister misiniz? İnternet Mühendisliği Görev Gücü (IETF) örneklerine göz atın.
WebRTC'nin, teklif veya yanıtın SDP metnindeki değerler düzenlenerek yerel veya uzak açıklama olarak ayarlanmadan önce değiştirilebileceği şekilde tasarlandığını unutmayın. Örneğin, varsayılan codec'i ve bit hızını ayarlamak için appr.tc'deki preferAudioCodec() işlevi kullanılabilir. SDP'yi JavaScript ile değiştirmek biraz zahmetlidir ve WebRTC'nin gelecekteki sürümlerinde bunun yerine JSON kullanılıp kullanılmaması gerektiği konusunda tartışmalar vardır ancak SDP'yi kullanmaya devam etmenin bazı avantajları vardır.
RTCPeerConnection API'si ve sinyalizasyon: Teklif, yanıt ve aday
RTCPeerConnection, WebRTC uygulamalarının eşler arasında bağlantı oluşturmak ve ses ile video iletişimi kurmak için kullandığı API'dir.
Bu süreci başlatmak için RTCPeerConnection iki görev üstlenir:
- Çözünürlük ve codec özellikleri gibi yerel medya koşullarını belirleme Bu, teklif ve yanıt mekanizması için kullanılan meta verilerdir.
- Uygulamanın ana makinesi için adaylar olarak bilinen potansiyel ağ adreslerini alma.
Bu yerel veriler belirlendikten sonra, uzak eşle bir sinyal mekanizması aracılığıyla paylaşılmalıdır.
Ayşe'nin Elif'i aramaya çalıştığını varsayalım. Yanıt mekanizmasının tüm ayrıntılarıyla işleyişi şu şekildedir:
- Alice bir
RTCPeerConnectionnesnesi oluşturur. - Alev,
RTCPeerConnectioncreateOffer()yöntemiyle bir teklif (SDP oturum açıklaması) oluşturur. - Alice,
setLocalDescription()adlı kişiyi arayarak teklifini iletiyor. - Alice, teklifi dizeye dönüştürür ve bir sinyal mekanizması kullanarak Eve'e gönderir.
- Eve, Alice'in teklifini iletmek için
setRemoteDescription()ile iletişime geçer. BöyleceRTCPeerConnection, Alice'in kurulumundan haberdar olur. - Eve,
createAnswer()yöntemini çağırır ve bu yöntemin başarılı geri çağırma işlevine yerel oturum açıklaması (Eve'in yanıtı) iletilir. - Eve,
setLocalDescription()yöntemini çağırarak yanıtını yerel açıklama olarak ayarlar. - Eve daha sonra dizeye dönüştürülmüş yanıtını Alice'e göndermek için sinyal mekanizmasını kullanır.
- Alice,
setRemoteDescription()kullanarak Eve'in yanıtını uzak oturum açıklaması olarak ayarlar.
Alice ve Eve'in ağ bilgilerini de paylaşması gerekir. "Aday bulma" ifadesi, ICE çerçevesini kullanarak ağ arayüzlerini ve bağlantı noktalarını bulma sürecini ifade eder.
- Alice,
onicecandidateişleyicisi olan birRTCPeerConnectionnesnesi oluşturur. - İşleyici, ağ adayları kullanılabilir olduğunda çağrılır.
- İşleyicide Alice, dizeye dönüştürülmüş aday verilerini sinyal kanalı üzerinden Eve'e gönderir.
- Eve, Alice'ten bir aday mesajı aldığında, adayı uzak eş açıklamasına eklemek için
addIceCandidate()yöntemini çağırır.
JSEP, ICE Candidate Trickling'i destekler. Bu sayede arayan, ilk tekliften sonra aranan kişiye kademeli olarak adaylar sunabilir ve aranan kişi, tüm adayların gelmesini beklemeden arama üzerinde işlem yapmaya ve bağlantı kurmaya başlayabilir.
Sinyal için WebRTC kodu yazma
Aşağıdaki kod snippet'i, tüm sinyal sürecini özetleyen bir W3C kod örneğidir. Kod, bir sinyal mekanizmasının (SignalingChannel) var olduğunu varsayar. Sinyal alışverişi 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 süreçlerini çalışırken görmek için simpl.info RTCPeerConnection adresini ziyaret edin ve tek sayfalık görüntülü sohbet örneği için konsol günlüğüne bakın. 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ü indirebilirsiniz.
Benzerleri keşfetme
Bu, "Konuşacak birini nasıl bulurum?" sorusunun daha süslü bir ifadesidir.
Telefon aramaları için telefon numaralarınız ve rehberleriniz vardır. Online görüntülü sohbet ve mesajlaşma için kimlik ve iletişim durumu yönetim sistemlerinin yanı sıra kullanıcıların oturum başlatabileceği bir yöntem gerekir. WebRTC uygulamalarında istemcilerin birbirlerine arama başlatmak veya aramaya katılmak istediklerini bildirmeleri gerekir.
Eş bulma mekanizmaları WebRTC tarafından tanımlanmaz ve burada seçeneklere girmezsiniz. Bu işlem, bir URL'yi e-posta 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 edersiniz. Geliştirici Chris Ball, WebRTC görüşmesi katılımcılarının anlık mesajlaşma, e-posta veya posta güvercini gibi istedikleri mesajlaşma hizmetiyle meta veri alışverişi yapmasına olanak tanıyan ilgi çekici bir sunucusuz WebRTC denemesi oluşturdu.
Sinyal hizmetini nasıl oluşturabilirsiniz?
Tekrar belirtmek gerekirse, sinyal protokolleri ve mekanizmaları WebRTC standartları tarafından tanımlanmaz. Seçiminiz ne olursa olsun, istemciler arasında sinyal mesajları ve uygulama verileri alışverişi yapmak için bir aracı sunucuya ihtiyacınız vardır. Maalesef bir web uygulaması internete "Beni arkadaşıma bağla!" diye bağıramaz.
Neyse ki sinyal mesajları küçüktür ve çoğunlukla aramanın başında paylaşılır. Görüntülü sohbet oturumu için appr.tc ile yapılan testlerde, sinyal hizmeti tarafından toplamda yaklaşık 30-45 mesaj işlendi ve tüm mesajların toplam boyutu yaklaşık 10 KB oldu.
WebRTC sinyal hizmetleri, bant genişliği açısından nispeten az talepkar olmanın yanı sıra, yalnızca mesajları iletmeleri ve hangi istemcilerin bağlı olduğu gibi az miktarda oturum durumu verisini saklamaları gerektiğinden çok fazla işlem veya bellek tüketmez.
Sunucudan istemciye push mesajları gönderme
Sinyal alışverişi için kullanılan mesaj hizmeti çift yönlü olmalıdır: istemciden sunucuya ve sunucudan istemciye. Çift 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 aktarmak için uzun yıllar boyunca uzun yoklama gibi çeşitli hileler geliştirilmiştir.
EventSource API,
sunucu tarafından gönderilen etkinlikleri, yani bir web sunucusundan tarayıcı istemcisine
HTTP aracılığıyla gönderilen verileri 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 hizmeti, arayanın XHR isteğiyle gönderdiği mesajı EventSource üzerinden aranan kişiye iletir.
WebSocket, tam çift yönlü istemci-sunucu iletişimi için tasarlanmıştır. Bu, mesajların aynı anda her iki yönde de akabileceği anlamına gelir. Yalnızca WebSocket veya sunucu tarafından gönderilen etkinlikler (EventSource) ile oluşturulan bir sinyal hizmetinin avantajlarından biri, bu API'lerin arka ucunun PHP, Python ve Ruby gibi diller için çoğu web barındırma paketinde yaygın olarak kullanılan çeşitli web çerçevelerinde uygulanabilmesidir.
WebRTC'yi destekleyen tüm tarayıcılar WebSocket'i de destekler. İletilerin şifrelenmemiş olarak ele geçirilmesini önlemek ve proxy geçişiyle ilgili sorunları azaltmak 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 High Performance Browser Networking (Yüksek Performanslı Tarayıcı Ağları) adlı kitabındaki WebRTC bölümünü okuyun.
WebRTC istemcilerinin Ajax üzerinden bir mesajlaşma sunucusunu tekrar tekrar yoklamasını sağlayarak sinyal alışverişini yönetebilirsiniz ancak bu, çok sayıda gereksiz ağ isteğine yol açar ve bu durum özellikle mobil cihazlar için sorun teşkil eder. Oturum oluşturulduktan sonra bile eşlerin, diğer eşler tarafından yapılan değişiklikler veya oturum sonlandırma durumunda sinyal mesajlarını sorgulaması gerekir. WebRTC Book uygulama örneği, yoklama sıklığıyla ilgili bazı optimizasyonlarla bu seçeneği kullanır.
Ölçek sinyali
Sinyal hizmeti, istemci başına nispeten az bant genişliği ve CPU tüketse de popüler bir uygulamanın sinyal sunucuları, farklı konumlardan gelen çok sayıda mesajı yüksek düzeyde eşzamanlılıkla işlemek zorunda kalabilir. Çok fazla trafik alan WebRTC uygulamaları, önemli miktarda yükü kaldırabilecek sinyal sunucularına ihtiyaç duyar. Burada ayrıntılara girmeyeceksiniz ancak yüksek hacimli, yüksek performanslı mesajlaşma için aşağıdakiler de dahil olmak üzere çeşitli seçenekler vardır:
eXtensible Messaging and Presence Protocol (XMPP), anlık mesajlaşma için geliştirilmiş bir protokoldür ve sinyalizasyon için kullanılabilir. Sunucu uygulamaları arasında ejabberd ve Openfire yer alır. Strophe.js gibi JavaScript istemcileri, çift yönlü akışı taklit etmek için BOSH'u kullanır ancak BOSH, WebSocket'e kıyasla verimsiz olabilir ve ölçeklendirme konusunda yetersiz kalabilir.
ZeroMQ (TokBox tarafından Rumour hizmeti için kullanılır) ve OpenMQ gibi açık kaynak kitaplıklar (NullMQ, WebSocket üzerinden STOMP protokolünü kullanarak ZeroMQ kavramlarını web platformlarına uygular.)
Pusher ve Kaazing gibi WebSocket kullanan ticari bulut mesajlaşma platformları (uzun yoklamaya geri dönebilirler).
vLine gibi ticari WebRTC platformları
Node'da Socket.io ile sinyal hizmeti oluşturma
Aşağıda, Node üzerinde Socket.io ile oluşturulmuş bir sinyal hizmeti kullanan web uygulamasının kodu verilmiştir. Socket.io'nun tasarımı, mesaj alışverişi için bir hizmet oluşturmayı kolaylaştırır ve Socket.io, yerleşik oda kavramı nedeniyle özellikle WebRTC sinyalizasyonu için uygundur. Bu örnek, canlı sürümde kullanımdan ziyade nispeten az sayıda kullanıcı için tasarlanmıştır.
Socket.io, yedeklerle birlikte WebSocket kullanır: AJAX uzun yoklama, AJAX çok parçalı akış, Forever Iframe ve JSONP yoklama. Çeşitli arka uçlara taşınmış olsa da en çok bu örnekte kullanılan Node sürümüyle bilinir.
Bu örnekte WebRTC yoktur. Bu örnek, bir web uygulamasına sinyal oluşturma özelliğinin nasıl ekleneceğini göstermek için tasarlanmıştır. İstemciler bir odaya katılıp mesaj alışverişinde bulunurken neler olduğunu görmek için konsol günlüğünü görüntüleyin. Bu WebRTC codelab'inde, bunu eksiksiz bir WebRTC görüntülü sohbet uygulamasına nasıl entegre edeceğinizle ilgili adım adım talimatlar verilmiştir.
Müşteri index.html:
<!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 başvurulan JavaScript dosyası main.js şöyledir:
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ı şu şekildedir:
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);
});
});
Bu uygulamayı localhost'ta çalıştırmak için Node.js, Socket.IO ve node-static'e ihtiyacınız vardır. Socket.IO ve node-static'i yüklemek için uygulama dizininizdeki bir terminalden npm komutunu ç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 adresini açın. Herhangi bir tarayıcıda yeni bir sekme veya pencere açıp localhost:2013 sayfasını 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ına basarak Google Chrome Geliştirici Araçları üzerinden konsola erişebilirsiniz.
Sinyal için hangi yaklaşımı seçerseniz seçin, arka ucunuzun ve istemci uygulamanızın bu örneğe benzer hizmetler sağlaması gerekir.
Sinyallerle ilgili dikkat edilmesi gerekenler
RTCPeerConnection,setLocalDescription()çağrılana kadar aday toplamaya başlamaz. Bu, JSEP IETF taslağında zorunlu kılınmıştır.- Trickle ICE'dan yararlanın. Adaylar geldiğinde hemen
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 olan ç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ç kod yazmak istemiyorsanız vLine, OpenTok ve Asterisk gibi şirketlerin sunduğu eksiksiz ticari WebRTC platformlarını kullanabilirsiniz.
Ericsson, WebRTC'nin ilk günlerinde Apache üzerinde PHP kullanarak bir sinyal sunucusu oluşturmuştu. Bu biraz eski bir yöntem olsa da benzer bir şey düşünüyorsanız koda bakmanızda fayda var.
Sinyal güvenliği
Tüm WebRTC bileşenleri için şifreleme zorunludur.
Ancak sinyal mekanizmaları WebRTC standartları tarafından tanımlanmadığından sinyal güvenliğini sağlamak size kalmıştır. Saldırganlar sinyalizasyonu ele geçirmeyi başarırsa oturumları durdurabilir, bağlantıları yönlendirebilir ve içerik kaydedebilir, değiştirebilir veya ekleyebilir.
Sinyal alışverişini güvence altına almanın en önemli yolu, güvenli protokoller kullanmaktır: HTTPS ve WSS (ör. TLS). Bu sayede, iletilerin şifrelenmemiş olarak ele geçirilmesi önlenir. Ayrıca, sinyal mesajlarını aynı sinyal sunucusunu kullanan diğer arayanlar tarafından erişilebilecek şekilde yayınlamamaya dikkat edin.
NAT'ler ve güvenlik duvarlarıyla başa çıkma
WebRTC uygulamaları, meta veri sinyali için bir aracı sunucu kullanır ancak oturum oluşturulduktan sonra gerçek medya ve veri akışı için RTCPeerConnection, istemcileri doğrudan veya eşler arası 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 ise çoğu cihaz bir veya daha fazla NAT katmanının arkasında bulunur, bazılarında belirli bağlantı noktalarını ve protokolleri engelleyen antivirüs yazılımları vardır ve çoğu cihaz proxy'lerin ve kurumsal güvenlik duvarlarının arkasındadır. Güvenlik duvarı ve NAT, evdeki Wifi yönlendirici gibi aynı cihaz tarafından uygulanabilir.
WebRTC uygulamaları, gerçek dünyadaki ağ oluşturma karmaşıklıklarının üstesinden gelmek için ICE çerçevesini kullanabilir. Bunu etkinleştirmek için uygulamanızın ICE sunucu URL'lerini RTCPeerConnection öğesine 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, öncelikle bir cihazın işletim sistemi 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 cihazlarda başarısız olur) ICE, bir 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.
Başka bir deyişle, harici bir ağ adresi almak için STUN sunucusu, doğrudan (eşler arası) bağlantı başarısız olursa trafiği aktarmak için TURN sunucuları kullanılır.
Her TURN sunucusu STUN'u destekler. TURN sunucusu, yerleşik ek aktarma işlevine sahip bir STUN sunucusudur. ICE, NAT kurulumlarının karmaşıklıklarıyla da başa çıkar. Gerçekte NAT delme işlemi için genel IP:bağlantı noktası adresinden daha fazlası gerekebilir.
STUN ve TURN sunucularının URL'leri, RTCPeerConnection oluşturucusunun ilk bağımsız değişkeni olan iceServers yapılandırma nesnesinde bir WebRTC uygulaması tarafından (isteğe bağlı olarak) 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 bilgileri aldıktan sonra ICE sihrini otomatik olarak gerçekleştirir. RTCPeerConnection, eşler arasındaki en iyi yolu bulmak için ICE çerçevesini kullanır ve gerektiğinde STUN ve TURN sunucularıyla çalışır.
STUN
NAT'ler, cihazlara özel bir yerel ağda kullanılacak 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 sorunu çözmek için STUN kullanır.
STUN sunucuları herkese açık internette bulunur ve tek bir görevi vardır: Gelen bir isteğin (NAT arkasında çalışan bir uygulamadan) IP:bağlantı noktası adresini kontrol etmek ve bu adresi yanıt olarak geri göndermek. Başka bir deyişle uygulama, IP:bağlantı noktasını herkese açık bir perspektiften keşfetmek için STUN sunucusu kullanır. Bu işlem, bir WebRTC eşinin kendisi için herkese açık bir adres almasını ve ardından doğrudan bağlantı kurmak için bu adresi bir sinyal mekanizması aracılığıyla başka bir eşe iletmesini sağlar.
STUN sunucularının çok fazla işlem yapması veya çok fazla bilgi hatırlaması gerekmez. Bu nedenle, nispeten düşük özellikli STUN sunucuları çok sayıda isteği işleyebilir.
Çoğu WebRTC görüşmesi, STUN kullanarak başarılı bir şekilde bağlantı kurar. Ancak güvenlik duvarlarının ve karmaşık NAT yapılandırmalarının arkasındaki eşler arasındaki görüşmelerde bu oran daha düşük olabilir.
DÖNÜŞ
RTCPeerConnection, UDP üzerinden eşler arasında doğrudan iletişim kurmaya çalışır.
Bu işlem başarısız olursa RTCPeerConnection, TCP'ye başvurur. Bu yöntem başarısız olursa yedek olarak TURN sunucuları kullanılabilir. Bu sunucular, uç noktalar arasında veri aktarımı yapar.
Tekrar belirtmek gerekirse TURN, eşler arasında ses, video ve veri akışını aktarmak için kullanılır, sinyal verilerini aktarmak için kullanılmaz.
TURN sunucularının herkese açık adresleri vardır. Bu sayede, eşler güvenlik duvarlarının veya proxy'lerin arkasında olsa bile eşler tarafından erişilebilirler. TURN sunucularının tek bir görevi vardır: Akışı aktarmak. STUN sunucularından farklı olarak, doğası gereği çok fazla bant genişliği tüketirler.
Bu şemada TURN'ün işleyişi gösterilmektedir. Yalnızca STUN kullanmak başarılı olmadığından her eş bir TURN sunucusu kullanır.
STUN ve TURN sunucularını dağıtma
Google, test için appr.tc tarafından kullanılan herkese açık bir STUN sunucusu (stun.l.google.com:19302) çalıştırır. Üretim STUN/TURN hizmeti için rfc5766-turn-server'ı kullanın. STUN ve TURN sunucularının kaynak kodu GitHub'da mevcuttur. Burada sunucu kurulumuyla ilgili çeşitli bilgi kaynaklarının bağlantılarını da bulabilirsiniz. Amazon Web Services için bir sanal makine görüntüsü de mevcuttur.
Alternatif bir TURN sunucusu, kaynak kodu olarak ve AWS için de kullanılabilen restund'dur. Compute'ta geri ödeme ayarlayabilirsiniz :
- tcp=443, udp/tcp=3478 için güvenlik duvarını gerektiği şekilde açın.
- Her bir genel IP için bir tane olmak üzere dört örnek oluşturun (Standart Ubuntu 12.06 görüntüsü).
- Yerel güvenlik duvarı yapılandırmasını ayarlayın (HERHANGİ birinden HERHANGİ birine izin verin).
- Araçları yükleyin:
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 restund'u alın ve paketi açın.
wgethancke.name/restund-auth.patch adresinden indirin vepatch -p1 < restund-auth.patchile uygulayın.- Libre ve restund için
make,sudo make installkomutunu çalıştırın. restund.confdosyası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/etcdizinine kopyalayın.restund/etc/restundöğesini/etc/init.d/klasörüne kopyalayın.- Restund'u yapılandırma:
LD_LIBRARY_PATH. kümerestund.conföğesini/etc/restund.confklasörüne kopyalayın.restund.confdeğerini sağdaki 10'u kullanacak şekilde ayarlayın. IP adresi.
- Restund'u çalıştırma
- Uzak makineden stund istemcisini kullanarak test edin:
./client IP:port
Ç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, bire bir görüşmenin ötesinde çok sayıda kullanım alanı vardır. Örneğin, bir grup iş arkadaşı arasında video konferans veya tek bir konuşmacı ve yüzlerce ya da milyonlarca izleyicinin katıldığı herkese açık bir etkinlik.
Bir WebRTC uygulaması, her uç noktanın bir ağ yapılandırmasındaki diğer tüm uç noktalara bağlanması için birden fazla RTCPeerConnection kullanabilir. Bu, talky.io gibi uygulamaların kullandığı yaklaşımdır ve az sayıda eş için son derece iyi çalışır. Bu sayının aşılması, özellikle mobil uygulama istemcileri için aşırı işlem ve bant genişliği tüketimine neden olur.
Alternatif olarak, bir WebRTC uygulaması, akışları yıldız yapılandırmasındaki diğer tüm uç noktalara dağıtmak için bir uç nokta seçebilir. Ayrıca bir sunucuda WebRTC uç noktası çalıştırabilir ve kendi yeniden dağıtım mekanizmanızı oluşturabilirsiniz (webrtc.org tarafından örnek bir istemci uygulaması sağlanır).
Bir RTCPeerConnection'den elde edilen MediaStream,
başka bir için giriş olarak kullanılabilir. Bu, bir web uygulamasının hangi eşe bağlanacağını seçerek çağrı yönlendirmeyi işlemesine olanak tanıdığı için daha esnek mimariler sağlayabilir. Bunun nasıl çalıştığını görmek için WebRTC samples Peer connection relay ve WebRTC samples Multiple peer connections sayfalarına bakın.
Çok noktalı kontrol birimi
Ç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, video konferanslarda farklı çözünürlükler, codec'ler ve kare hızlarıyla başa çıkabilir, kod dönüştürme işlemlerini gerçekleştirebilir, seçmeli akış yönlendirmesi yapabilir ve ses ile videoyu karıştırabilir veya kaydedebilir. Çok taraflı görüşmelerde, özellikle birden fazla video girişinin nasıl gösterileceği ve birden fazla kaynaktan gelen sesin nasıl karıştırılacağı gibi dikkate alınması gereken çeşitli sorunlar vardır. vLine gibi bulut platformları da trafik yönlendirmeyi optimize etmeye çalışır.
Eksiksiz bir MCU donanım paketi satın alabilir veya kendi paketinizi 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 kaynaklı bir MCU üretir. OpenTok'ta Mantis vardır.
Tarayıcıların ötesinde: VoIP, telefonlar ve mesajlaşma
WebRTC'nin standartlaştırılmış yapısı, tarayıcıda çalışan bir WebRTC uygulaması ile telefon veya video konferans sistemi gibi başka bir iletişim platformunda çalışan bir cihaz ya da platform arasında iletişim kurulmasını mümkün kılar.
SIP, VoIP ve video konferans sistemleri tarafından kullanılan bir sinyal protokolüdür. WebRTC web uygulaması ile SIP istemcisi (ör. video konferans sistemi) arasında iletişim kurulabilmesi için WebRTC'nin sinyal alışverişine aracılık edecek bir proxy sunucusuna ihtiyacı vardır. Sinyal, ağ geçidinden geçmelidir ancak iletişim kurulduktan sonra SRTP trafiği (video ve ses) eşler arası akabilir.
Sabit telefon şebekesi (PSTN), tüm "eski tip" analog telefonların devre anahtarlamalı ağıdır. WebRTC web uygulamaları ile telefonlar arasındaki aramalar için trafiğin bir PSTN ağ geçidinden geçmesi gerekir. Benzer şekilde, WebRTC web uygulamalarının anlık mesajlaşma istemcileri gibi Jingle uç noktalarıyla iletişim kurmak için aracı bir XMPP sunucusuna ihtiyacı vardır. Jingle, mesajlaşma hizmetlerinde ses ve video özelliklerini etkinleştirmek için Google tarafından XMPP'nin bir uzantısı olarak geliştirilmiştir. Mevcut WebRTC uygulamaları, başlangıçta Talk için geliştirilen bir Jingle uygulaması olan C++ libjingle kitaplığını temel alır.
Birçok uygulama, kitaplık ve platform, WebRTC'nin dış dünyayla iletişim kurma özelliğinden yararlanır. Örneğin:
- jsSIP: JavaScript SIP kitaplığı
- Phono: Eklenti olarak oluşturulmuş açık kaynak JavaScript telefon API'si
- Twilio: ses ve mesajlaşma
Daha fazla bilgi
- WebRTC API belgelerini okuyun.
- WebRTC codelab, Node üzerinde çalışan bir Socket.io sinyal hizmeti kullanarak video ve metin sohbet uygulaması oluşturma hakkında adım adım talimatlar sağlar.
- Chris Wilson'ın SFHTML5 sunumu: WebRTC Uygulamalarına Giriş
350 sayfalık WebRTC: APIs and RTCWEB Protocols of the HTML5 Real-Time Web kitabı, veri ve sinyal yolları hakkında birçok ayrıntı sağlar ve çok sayıda ayrıntılı ağ topolojisi diyagramı içerir.