WebRTC uygulaması için gereken arka uç hizmetlerini derleme

Sinyal nedir?

Sinyal, iletişimi koordine etme sürecidir. Bir WebRTC uygulamasının arama ayarlaması için istemcilerinin aşağıdaki bilgileri değiş tokuş etmesi 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ışarıdan gördüğü şekilde, ana makinenin IP adresi ve bağlantı noktası gibi ağ verileri

Bu sinyal sürecinde, istemcilerin iletiler arasında gidip gelmeleri için bir yöntem gerekir. Bu mekanizma, WebRTC API'leri tarafından uygulanmamaktadır. Bunu kendi başınıza oluşturmanız gerekir. Bu makalenin ilerleyen kısımlarında sinyal hizmeti derlemenin yollarını öğreneceksiniz. Ancak öncelikle biraz bağlama ihtiyacınız var.

Sinyal neden WebRTC tarafından tanımlanmıyor?

Yedekliliği önlemek ve yerleşik teknolojilerle uyumluluğu en üst düzeye çıkarmak için, sinyal yöntemleri ve protokolleri WebRTC standartları tarafından belirtilmedi. Bu yaklaşım, JavaScript Oturum Oluşturma Protokolü (JSEP) ile özetlenmiştir:

JSEP'nin mimarisi ayrıca tarayıcının sinyal durumu makinesi olarak çalışmak için durumu kaydetme zorunluluğunu da önler. Örneğin, bir sayfa her yeniden yüklendiğinde sinyal verileri kaybolduysa bu durum sorunlu olabilir. Bunun yerine, sinyal durumu bir sunucuya kaydedilebilir.

JSEP mimari şeması
JSEP mimarisi

JSEP, yukarıda bahsedilen medya meta verileri olan offer ve answer arasındaki değişimi gerektirir. Teklifler ve yanıtlar, aşağıdakine benzer 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 bomboşluklarının tam olarak ne anlama geldiğini bilmek ister misiniz? İnternet Mühendisliği Görev Gücü (IETF) örneklerine göz atın.

WebRTC'nin, SDP metnindeki değerleri düzenleyerek teklif veya yanıtın yerel veya uzak açıklama olarak belirlenmeden önce ayarlanabileceğ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'nin JavaScript ile değiştirilmesi biraz zahmetlidir. WebRTC'nin gelecekteki sürümlerinin bunun yerine JSON kullanıp kullanmayacağı konusunda tartışmalar yapılıyor ancak SDP'ye bağlı kalmanın bazı avantajları var.

RTCPeerConnection API ve sinyal: Teklif, yanıt ve aday

RTCPeerConnection, WebRTC uygulamaları tarafından eşler arasında bağlantı oluşturmak, ses ve görüntü iletmek için kullanılan API'dir.

Bu işlemi başlatmak için RTCPeerConnection aracının iki görevi vardır:

  • Çözünürlük ve codec özellikleri gibi yerel medya koşullarını belirleyin. Bu, teklif-cevap mekanizması için kullanılan meta veridir.
  • Uygulamanın ana makinesinin (adaylar olarak bilinen) potansiyel ağ adreslerini alın.

Bu yerel veriler doğrulandıktan sonra uzak eşle bir sinyal mekanizması üzerinden değiştirilmelidir.

Ayşe'nin Ece'yi aramaya çalıştığını hayal edin. Teklif/yanıt mekanizmasının tüm ayrıntılarıyla burada verilmiştir:

  1. Ayla bir RTCPeerConnection nesnesi oluşturur.
  2. Ayla, RTCPeerConnection createOffer() yöntemini kullanarak bir teklif (STP oturum açıklaması) oluşturur.
  3. Ayşe, sunduğu teklifle ilgili olarak setLocalDescription() adlı işletmeyi arar.
  4. Ayşe, teklifi dizeler ve Efe'ye göndermek için bir sinyal mekanizması kullanır.
  5. Eve, Ayşe'nin teklifiyle setRemoteDescription() adlı kişiyi arar. Böylece RTCPeerConnection, Ayşe'nin kurulumundan haberdar olur.
  6. Eve createAnswer() adlı kişiyi arar ve bunun için başarılı geri çağırma, yerel oturum açıklamasından (Eve'nin yanıtı) geçer.
  7. Eve setLocalDescription() numarasını arayarak yanıtını yerel açıklama olarak belirler.
  8. Eve daha sonra sinyal mekanizmasını kullanarak net yanıtı Aylin'e gönderir.
  9. Ayşe, setRemoteDescription() kullanarak Ece'nin yanıtını uzak oturum açıklaması olarak ayarlar.

Ayşe ve Ece'nin ağ bilgilerini de paylaşması gerekir. "Aday bulma" ifadesi, ICE çerçevesini kullanarak ağ arayüzlerini ve bağlantı noktalarını bulma işlemini ifade eder.

  1. Ayşe, onicecandidate işleyicisi ile bir RTCPeerConnection nesnesi oluşturur.
  2. İşleyici, ağ adayları kullanılabilir olduğunda çağrılır.
  3. İşleyicide Aylin, dizeleştirilmiş aday verilerini kendi sinyal kanalı üzerinden Ece'ye gönderir.
  4. Ece, Ayşe'den bir aday mesajı aldığında adayı uzaktaki benzerin açıklamasına eklemek için addIceCandidate() numarasını arar.

JSEP, ICE Candidate Trickling'i (ICE Candidate Trickling) destekler. Bu özellik, arayanın ilk tekliften sonra aranan kişiye aşamalı olarak adayları sağlamasına ve arayanın, görüşmede harekete geçmesini ve tüm adayların gelmesini beklemeden bağlantı kurmasına olanak tanır.

Sinyal için Code WebRTC

Aşağıdaki kod snippet'i, tüm sinyal sürecini özetleyen bir W3C kodu örneğidir. Kod, SignalingChannel adlı bir sinyal mekanizmasının varlığını varsayar. Sinyal verme işlemi daha sonra daha ayrıntılı bir şekilde açıklanacaktı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 exchange işlemlerinin nasıl çalıştığını görmek için simpl.info RTCPeerConnection adresine bakın ve tek sayfalık görüntülü sohbet örneği için konsol günlüğüne bakın. Daha fazlasını isterseniz Google Chrome'daki about://webrtc-internals sayfasından veya Opera'daki opera://webrtc-internals sayfasından WebRTC sinyalleri ve istatistiklerinin tam dökümünü indirin.

Emsal keşfi

Bu, "Konuşacak birini nasıl bulurum?" diye sormanın ilginç bir yoludur.

Telefon görüşmeleri için telefon numaralarınız ve dizinleriniz vardır. Online görüntülü sohbet ve mesajlaşma için kimlik ve durum yönetim sistemlerine, ayrıca kullanıcıların oturum başlatabileceği bir yönteme ihtiyacınız vardır. WebRTC uygulamalarında, istemcilerin görüşme başlatmak veya görüşmeye katılmak istediklerini bildirmeleri için bir yöntem sunulmalıdır.

Eş keşif mekanizmaları WebRTC tarafından tanımlanmaz ve buradaki seçeneklere girmezsiniz. Süreç, bir URL'ye e-posta göndermek veya ileti göndermek kadar basit olabilir. Talky, tawk.to ve Tarayıcı Toplantısı gibi görüntülü sohbet uygulamaları için özel bir bağlantı paylaşarak kullanıcıları bir görüşmeye davet edersiniz. Geliştirici Chris Ball, WebRTC arama katılımcılarının IM, e-posta veya homing güvercin gibi herhangi bir mesajlaşma hizmetinden meta veri alışverişinde bulunmasını sağlayan ilginç bir serverless-webrtc denemesi oluşturdu.

Sinyal hizmeti nasıl oluşturulur?

Tekrarlamak gerekirse, sinyal protokolleri ve mekanizmaları WebRTC standartları tarafından tanımlanmamıştır. Hangisini seçerseniz seçin, istemciler arasında sinyal mesajları ve uygulama verileri alışverişi için ara sunucuya ihtiyacınız vardır. Ne yazık ki 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 gönderilir. Görüntülü sohbet oturumu için appr.tc ile test edilen toplamda 30-45 mesaj sinyal hizmeti tarafından işlendi ve toplam boyutu yaklaşık 10 KB'lık tüm mesajlar için yapıldı.

WebRTC sinyal hizmetleri, bant genişliği açısından oldukça talepkar olmasının yanı sıra, yalnızca mesajları aktarmaları ve hangi istemcilerin bağlı olduğu gibi küçük bir oturum durumu verisini saklamaları gerektiğinden fazla işlem veya bellek tüketmez.

Sunucudan istemciye mesaj aktarma

Sinyaller için mesaj hizmetinin iki yönlü olması gerekir: istemciden sunucuya ve sunucudan istemciye. Çift yönlü iletişim HTTP istemci/sunucu istek/yanıt modeline aykırıdır, ancak bir web sunucusunda çalışan bir hizmetten tarayıcıda çalışan bir web uygulamasına veri aktarmak için yıllar içinde uzun yoklama gibi çeşitli saldırılar geliştirilmiştir.

Kısa süre önce, EventSource API geniş çapta uygulanmaya başladı. Bu işlem, sunucu tarafından gönderilen etkinlikleri, yani HTTP aracılığıyla bir web sunucusundan tarayıcı istemcisine gönderilen verileri etkinleştirir. EventSource tek yönlü mesajlaşma için tasarlanmıştır ancak sinyal mesajı alışverişi için bir hizmet oluşturmak amacıyla XHR ile birlikte kullanılabilir. Bir sinyal hizmeti, arayandan gelen ve XHR isteği tarafından iletilen bir mesajı EventSource yoluyla arayan kişiye iletir.

WebSocket, aynı anda iki yönde de gerçekleştirilen tam çift yönlü istemci-sunucu iletişimi için tasarlanmış, daha doğal bir çözümdür. Sadece WebSocket veya sunucu tarafından gönderilen etkinlikler (EventSource) ile oluşturulan sinyal hizmetinin avantajlarından biri, bu API'lerin arka ucunun PHP, Python ve Ruby gibi dillerin çoğu web barındırma paketinde yaygın olan çeşitli web çerçevelerinde uygulanabilmesidir.

Opera Mini dışındaki tüm modern tarayıcılar WebSocket'i ve daha da önemlisi, WebRTC'yi destekleyen tüm tarayıcılar hem masaüstü hem de mobil cihazlarda WebSocket'i destekler. İletilere şifrelenmemiş şekilde müdahale edilememesini sağlamak 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 Yüksek Performanslı Tarayıcı Ağ İletişimi başlıklı makalenin WebRTC bölümüne bakın.)

WebRTC istemcilerinin Ajax aracılığıyla bir mesajlaşma sunucusunu tekrar tekrar yok etmesini sağlayarak sinyalin işlenmesini sağlamak da mümkündür. Ancak bu durum çok sayıda gereksiz ağ isteğine yol açar. Bu da özellikle mobil cihazlar için sorun teşkil eder. Bir oturum oluşturulduktan sonra bile, değişiklik olması veya diğer eşler tarafından oturumun sonlandırılması durumunda eşlerin sinyal mesajları için anket yapması gerekir. WebRTC Book uygulama örneğinde bu seçenek, anket sıklığına yönelik bazı optimizasyonlarla birlikte kullanılmıştır.

Sinyalleri ölçeklendirin

Bir sinyal hizmeti istemci başına göreli olarak daha az bant genişliği ve CPU tüketse de, popüler bir uygulamanın sinyal sunucularının yüksek eşzamanlılık seviyeleriyle farklı konumlardan gelen çok sayıda mesajı işlemesi gerekebilir. Çok fazla trafik alan WebRTC uygulamaları, kayda değer bir yükü kaldırabilecek sinyal sunucularına ihtiyaç duyar. Burada ayrıntıya girilmeyecek ancak yüksek hacimli ve yüksek performanslı mesajlaşma için aşağıdakiler gibi çeşitli seçenekler mevcuttur:

  • İlk olarak anlık mesajlaşma için geliştirilen ve sinyal için kullanılabilecek Jabber-a protokolü olarak bilinen eXtensible Messaging and Presence Protocol (eXtensible mesajlaşma ve varlık protokolü) (XMPP) (Sunucu uygulamaları arasında ejabberd ve Openfire yer alır.) Strophe.js gibi JavaScript istemcileri, çift yönlü akış emülasyonu için BOSH'u kullanır. Ancak çeşitli nedenlerle BOSH, WebSocket kadar verimli olmayabilir ve aynı nedenlerle iyi ölçeklenmeyebilir.) (Teğet olarak Jingle, ses ve videoyu etkinleştirmek için kullanılan bir XMPP uzantısıdır. WebRTC projesi, Jingle'ın C++ uygulaması olan libjingle kitaplığındaki ağ ve aktarım bileşenlerini kullanır.)

  • ZeroMQ (TokBox tarafından Rumour hizmetleri için kullanılır) ve OpenMQ (NullMQ, WebSocket üzerinden STOMP protokolünü kullanarak web platformlarına ZeroMQ kavramlarını uygular.) gibi açık kaynak kitaplıklar

  • Pusher, Kaazing ve PubNub gibi WebSocket kullanan (ancak uzun yoklamaya geri dönebilir) ticari bulut mesajlaşma platformları (PubNub'da ayrıca WebRTC için bir API bulunur.)

  • vLine gibi ticari WebRTC platformları

(Geliştirici Phil Leggetter'ın Gerçek Zamanlı Web Teknolojileri Kılavuzu mesajlaşma hizmetlerinin ve kitaplıklarının kapsamlı bir listesini sağlar.)

Düğümde Socket.io ile sinyal hizmeti derleme

Aşağıda, Socket.io üzerinde Socket.io ile oluşturulmuş bir sinyal hizmeti kullanan basit bir web uygulaması kodu verilmiştir. Socket.io'nun tasarımı, mesaj alışverişi için bir hizmet oluşturmayı kolaylaştırır. Socket.io ise yerleşik oda konsepti nedeniyle özellikle WebRTC sinyaline uygundur. Bu örnek, üretim düzeyinde bir sinyal hizmeti olarak ölçeklenmek üzere tasarlanmamıştır ancak nispeten az sayıda kullanıcı tarafından kolayca anlaşılabilir.

Socket.io, yedeklerle 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 Düğüm sürümüyle tanınıyor olabilir.

Bu örnekte WebRTC yok. Yalnızca web uygulamasına nasıl sinyal oluşturulduğunu göstermek için tasarlanmıştır. Müşteriler bir odaya katılıp mesaj gönderip alırken neler olduğunu görmek için konsol günlüğünü görüntüleyin. Bu WebRTC codelab'i, bunun eksiksiz bir WebRTC görüntülü sohbet uygulamasına nasıl entegre edileceğine ilişkin adım adım talimatlar sağlar.

index.html istemcisi:

<!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ını burada görebilirsiniz:

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ı burada 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 düğüm statik hakkında bilgi edinmenize gerek yoktur. Yalnızca bu örnekte kullanılmıştır.)

Bu uygulamayı localhost'ta çalıştırmak için Node, Socket.IO ve node-static'in yüklü olması gerekir. Düğüm Node.js'den indirilebilir (yükleme işlemi basit ve hızlıdır). Socket.IO ve node-static öğelerini 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ızdan localhost:2013 uygulamasını açın. Herhangi bir tarayıcıda yeni bir sekme veya pencere açıp localhost:2013 uygulamasını tekrar açın. Neler olduğunu öğrenmek için konsolu kontrol edin. Chrome ve Opera'da, Ctrl+Shift+J (veya Mac'te Command+Option+J) ile Google Chrome Geliştirici Araçları'nı kullanarak konsola erişebilirsiniz.

Sinyal için hangi yaklaşımı seçerseniz seçin, arka ucunuzun ve istemci uygulamanızın en azından bu örneğe benzer hizmetler sunması gerekir.

Sinyal kaçışları

  • RTCPeerConnection, setLocalDescription() çağrılana kadar adayları toplamaya başlamaz. Bu, JSEP IETF taslağında zorunludur.
  • Trickle ICE'den yararlanın. Adaylar ulaşır ulaşmaz addIceCandidate() numaralı telefonu arayın.

Hazır sinyal sunucuları

Kendi sunucunuzu yayınlamak istemiyorsanız önceki örnekte olduğu gibi Socket.IO kullanan ve WebRTC istemci JavaScript kitaplıklarıyla entegre edilmiş çeşitli WebRTC sinyal sunucuları vardır:

  • webRTC.io, WebRTC için kullanılan 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 şirketlerden eksiksiz ticari WebRTC platformları sunulmaktadır.

Ayrıca, WebRTC'nin ilk günlerinde Ericsson, Apache'de PHP kullanarak bir sinyal sunucusu oluşturdu. Bu yöntem artık biraz eski. Ancak benzer bir şey düşünüyorsanız koda bakmak yararlı olacaktır.

Sinyal güvenliği

"Güvenlik, hiçbir şeyi gerçekleştirmeme sanatıdır."

Salman Rushdie

Şifreleme tüm WebRTC bileşenleri için zorunludur.

Bununla birlikte, sinyal mekanizmaları WebRTC standartları tarafından tanımlanmadığından, sinyalin güvenli hale getirilmesi sizin sorumluluğunuzdadır. Sinyalleri ele geçirmeyi başaran bir saldırgan, oturumları durdurabilir, bağlantıları yeniden yönlendirebilir ve içerik kaydedebilir, değiştirebilir veya yerleştirebilir.

Sinyalin güvenliğini sağlamada en önemli faktör, iletilere şifrelenmemiş olarak müdahale edilmesini engelleyen güvenli protokoller (HTTPS ve WSS (örneğin, TLS)) kullanmaktır. Ayrıca, sinyal mesajlarını aynı sinyal sunucusunu kullanan diğer arayanların erişebileceği şekilde yayınlamamaya dikkat edin.

Sinyal aldıktan sonra: NAT'ler ve güvenlik duvarlarıyla başa çıkmak için ICE kullanın

Meta veri sinyali için WebRTC uygulamaları, bir ara sunucu kullanır. Ancak bir oturum kurulduğunda, gerçek medya ve veri akışı için RTCPeerConnection, istemcileri doğrudan veya eşler arası bağlamayı dener.

Daha basit bir dünyada her WebRTC uç noktasının, doğrudan iletişim kurmak için diğer eşlerle değiştirebileceği benzersiz bir adresi olur.

Eşler arası basit bağlantı
NAT'leri ve güvenlik duvarları olmayan bir dünya

Gerçekte, çoğu cihaz bir veya daha fazla NAT katmanının arkasında yaşar, bazılarında belirli bağlantı noktalarını ve protokolleri engelleyen virüsten koruma yazılımları bulunur, birçoğu da proxy'lerin ve kurumsal güvenlik duvarlarının arkasındadır. Güvenlik duvarı ve NAT, aslında aynı cihaz (örneğin, evdeki bir kablosuz ağ yönlendiricisi) tarafından uygulanabilir.

NAT&#39;lerin ve güvenlik duvarlarının arkasındaki eşler
Gerçek dünya

WebRTC uygulamaları, gerçek dünyadaki ağ iletişiminin karmaşıklıklarının üstesinden gelmek 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 hizmetine iletmesi gerekir.

ICE, meslektaşları arasında bağlantı kurmanın en iyi yolunu bulmaya çalışıyor. Tüm olasılıkları paralel olarak dener ve çalışan en verimli seçeneği seçer. ICE, öncelikle cihazın işletim sistemi ve ağ kartından alınan ana makine adresini kullanarak bağlantı kurmaya çalışır. Bu başarısız olursa (NAT'lerin arkasındaki cihazlar için de geçerlidir) ICE, STUN sunucusunu kullanarak harici bir adres alır ve bu başarısız olursa trafik bir TURN geçiş sunucusu üzerinden yönlendirilir.

Diğer bir deyişle, harici ağ adresini almak için STUN sunucusu kullanılır, doğrudan (eşler arası) bağlantı başarısız olursa trafiği aktarmak için TURN sunucuları kullanılır.

Tüm TURN sunucuları STUN'u destekler. TURN sunucusu, ek yerleşik geçiş işlevine sahip bir STUN sunucusudur. ICE, NAT kurulumlarının karmaşıklıklarıyla da başa çıkar. Gerçekte, NAT'de delik delme özelliği, genel bir IP:bağlantı noktası adresinden daha fazlasını gerektirebilir.

STUN ve/veya TURN sunucularının URL'leri (isteğe bağlı olarak), RTCPeerConnection oluşturucunun ilk bağımsız değişkeni olan iceServers yapılandırma nesnesindeki bir WebRTC uygulaması tarafından belirtilir. appr.tc için bu değer şöyle 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 büyüsü otomatik olarak gerçekleşir. RTCPeerConnection, benzerler arasındaki en iyi yolu belirlemek için ICE çerçevesini kullanır ve gerektiğinde STUN ve TURN sunucularıyla çalışır.

ŞU

NAT'ler, cihaza özel bir yerel ağda kullanılması için IP adresi sağlar ancak bu adres harici olarak kullanılamaz. Herkese açık adres olmadan WebRTC eşlerinin iletişim kurması mümkün olmaz. WebRTC, bu sorunu gidermek için STUN'u kullanır.

STUN sunucuları herkese açık internette bulunur ve basit bir görevi vardır. Gelen isteğin (NAT arkasında çalışan bir uygulamadan) IP:bağlantı noktası adresini kontrol etme ve yanıt olarak bu adresi geri gönderme. Diğer bir deyişle, uygulama, IP:bağlantı noktasını herkese açık perspektiften keşfetmek için bir STUN sunucusu kullanır. Bu işlem, WebRTC eşinin kendisi için herkese açık bir adres almasını ve doğrudan bağlantı oluşturmak amacıyla bu adresi bir sinyal mekanizması aracılığıyla başka bir eşe aktarmasını sağlar. (Pratikte, farklı NAT'ler farklı şekillerde çalışır ve birden fazla NAT katmanı olabilir ancak prensip aynıdır.)

STUN sunucularının fazla bir şey yapması veya çok fazla hatırlaması gerekmez. Dolayısıyla, nispeten düşük özellikli STUN sunucuları çok sayıda isteği işleyebilir.

Webrtcstats.com'a göre çoğu WebRTC çağrısı, STUN'u (%86) kullanarak başarıyla bağlantı kurar. Ancak bu oran, güvenlik duvarlarının arkasındaki eşler arasında ve karmaşık NAT yapılandırmaları için daha az olabilir.

STUN sunucusu kullanarak eşler arası bağlantı
Genel IP:bağlantı noktası adreslerini almak için STUN sunucularını kullanma

DÖN

RTCPeerConnection, UDP üzerinden eşler arasında doğrudan iletişim kurmaya çalışıyor. Bu başarısız olursa RTCPeerConnection, TCP'yi kullanır. Bu başarısız olursa TURN sunucuları yedek olarak kullanılabilir ve uç noktalar arasında veri geçişi yapabilir.

TURN, veri sinyali göndermek yerine benzerler arasında ses, video ve veri akışını aktarmak için kullanılır.

TURN sunucularının herkese açık adresleri olduğundan, eşler güvenlik duvarlarının veya proxy'lerin arkasında olsa bile eşler tarafından iletişim kurulabilir. TURN sunucularının kavramsal olarak basit bir görevi vardır: bir akışı aktarmak. Ancak STUN sunucularının aksine, yapıları gereği çok fazla bant genişliği harcarlar. Başka bir deyişle, TURN sunucularının daha güçlü olması gerekir.

STUN sunucusu kullanarak eşler arası bağlantı
Tam Monty: STUN, TURN ve sinyal gönderme

Bu diyagramda DÖNÜŞ NASIL işlevi gösterilmektedir. Saf STUN başarısız oldu, bu nedenle her eş bir TURN sunucusu kullanmaya çalışıyor.

STUN ve TURN sunucularını dağıtma

Test amacıyla Google, appr.tc tarafından kullanılan, herkese açık bir STUN sunucusu (stun.l.google.com:19302) çalıştırır. Bir üretim STUN/TURN hizmeti için rfc5766-turn-server'ı kullanın. STUN ve TURN sunucuları için kaynak kodu GitHub'da bulabilirsiniz. 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 kullanılabilir.

Kaynak kod olarak ve ayrıca AWS için kullanılabilen alternatif bir TURN sunucusu geri yüklenir. Compute Engine'de geri yükleme işlevini ayarlama talimatları aşağıda verilmiştir.

  1. tcp=443, udp/tcp=3478 için güvenlik duvarını gerektiği şekilde açın.
  2. Her genel IP için bir tane olmak üzere, Standard Ubuntu 12.06 görüntüsü olmak üzere dört örnek oluşturun.
  3. Yerel güvenlik duvarı yapılandırmasını ayarlayın (HERHANGİ BİRİNE izin verin).
  4. Araçları yükleyin: shell sudo apt-get install make sudo apt-get install gcc
  5. Libre'yi creytiv.com/re.html adresinden yükleyin.
  6. creytiv.com/restund.html adresinden geri yüklenen öğeleri getirin ve paketi açın./
  7. wget hancke.name/restund-auth.patch ve patch -p1 < restund-auth.patch ile başvurun.
  8. Libre ve restund için make, sudo make install komutunu çalıştırın.
  9. restund.conf IP adresini ihtiyaçlarınıza göre değiştirin (IP adreslerini değiştirin ve aynı paylaşılan gizli sırrı içerdiğinden emin olun) ve dosyayı /etc klasörüne kopyalayın.
  10. restund/etc/restund öğesini /etc/init.d/ klasörüne kopyalayın.
  11. Geri yüklemeyi yapılandırın:
    1. LD_LIBRARY_PATH ayarla.
    2. restund.conf öğesini /etc/restund.conf klasörüne kopyalayın.
    3. Sağdaki 10'u kullanmak için restund.conf değerini ayarlayın. IP adresi.
  12. Restund'ı çalıştır
  13. Uzak makinedeki stund istemcisini kullanarak test edin: ./client IP:port

Bire bir değil: Çok taraflı WebRTC

Ayrıca, Justin Uberti'nin TURN Hizmetlerine erişim için REST API ile ilgili önerdiği IETF standardına da göz atabilirsiniz.

Medya akışı için basit bire bir görüşmenin ötesine geçen kullanım alanları aklınıza gelebilir. Bir grup iş arkadaşıyla video konferans veya tek bir konuşmacı ile yüzlerce ya da milyonlarca görüntüleyenin bulunduğu herkese açık bir etkinlik buna örnek olarak verilebilir.

Bir WebRTC uygulaması, birden çok RTCPeerConnections kullanabilir. Böylece, her uç nokta, bir örgü yapılandırmasındaki diğer tüm uç noktalara bağlanır. talky.io gibi uygulamalar bu yaklaşımı benimsiyor ve az sayıda benzer uygulama için oldukça iyi sonuç veriyor. Bunun ötesinde, özellikle mobil istemciler için işlem ve bant genişliği kullanımı aşırı hale gelir.

Örgü: küçük n yönlü çağrı
Tam örgü topolojisi: Herkes herkesle bağlantı halinde

Alternatif olarak, bir WebRTC uygulaması, akışları yıldız yapılandırmasındaki diğer tüm kullanıcılara dağıtmak için bir uç nokta seçebilir. Sunucuda WebRTC uç noktası çalıştırıp kendi yeniden dağıtım mekanizmanızı da oluşturabilirsiniz (webrtc.org tarafından bir örnek istemci uygulaması sağlanır).

Chrome 31 ve Opera 18'den beri, bir RTCPeerConnection içindeki MediaStream başka bir tanesi için girdi olarak kullanılabilir. Bu, bir web uygulamasının diğer hangi eşe bağlanacağını seçerek çağrı yönlendirmeyi işleyebilmesini sağladığından daha esnek mimariler sağlayabilir. Bunu uygulamalı olarak görmek için WebRTC örnekleri Eş bağlantı geçişi ve WebRTC örnekleri Birden fazla eş bağlantısı konularına bakın.

Çok Noktalı Kontrol Ünitesi

Çok sayıda uç nokta için daha iyi bir seçenek, Çok Noktalı Kontrol Birimi (MCU) kullanmaktır. Bu sunucu, medyayı çok sayıda katılımcı arasında dağıtmak için köprü görevi görür. MCU'lar video konferanslarda farklı çözünürlükler, codec'ler ve kare hızlarıyla başa çıkabilir, kod dönüştürmeyi yönetebilir, akış yönlendirme yapabilir ve ses ile videoyu karıştırabilir ya da kaydedebilir. Çok taraflı görüşmelerde göz önünde bulundurulması gereken bir dizi sorun vardır. Özellikle birden fazla video girişinin görüntülenmesi ve birden fazla kaynaktan sesin karıştırılması gibi hususlar söz konusudur. vLine gibi bulut platformları da trafik yönlendirmesini optimize etmeye çalışır.

Eksiksiz bir MCU donanım paketi satın alabilir veya kendi donanım paketinizi oluşturabilirsiniz.

Cisco MCU5300&#39;ün arkadan görünümü
Cisco MCU'nun arkası

Birçok açık kaynaklı MCU yazılım seçeneği mevcuttur. Örneğin, Licode (önceki 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ış doğası, tarayıcıda çalışan bir WebRTC uygulaması ile telefon veya video konferans sistemi gibi başka bir iletişim platformunda çalışan cihaz veya 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şimi sağlamak için WebRTC'nin, sinyal uyumlulaştırmasını sağlayacak bir proxy sunucusuna ihtiyacı vardır. Sinyalin ağ geçidi üzerinden akması gerekir ancak iletişim kurulduktan sonra SRTP trafiği (video ve ses) doğrudan eşler arası akabilir.

Genel Anahtarlı Telefon Ağı (PSTN), tüm "basit eski" analog telefonların devre anahtarlı ağıdır. WebRTC web uygulamaları ile telefonlar arasındaki aramalarda trafiğin bir PSTN ağ geçidinden geçmesi gerekir. Benzer şekilde, WebRTC web uygulamaları da IM istemcileri gibi Jingle uç noktalarıyla iletişim kurmak için bir ara XMPP sunucusuna ihtiyaç duyar. Jingle, Google tarafından mesajlaşma hizmetleri için ses ve görüntüyü etkinleştirmek amacıyla XMPP'nin bir uzantısı olarak geliştirildi. Mevcut WebRTC uygulamaları, başlangıçta Talk için geliştirilen Jingle'ın bir uygulaması olan C++ libjingle kitaplığını temel alır.

Çeşitli uygulamalar, kitaplıklar ve platformlar WebRTC'nin dış dünyayla iletişim kurma özelliğinden yararlanır:

  • sipML5: açık kaynaklı bir JavaScript SIP istemcisi
  • jsSIP: JavaScript SIP kitaplığı
  • Phono: Eklenti olarak oluşturulmuş açık kaynak JavaScript telefon API'sı
  • Zingaya: Yerleştirilebilir bir telefon widget'ı
  • Twilio: Ses ve mesajlaşma
  • Uberconference: konferans

Ayrıca sipML5 geliştiricileri webrtc2sip ağ geçidini de oluşturmuştur. Tethr ve Tropo, WebRTC aracılığıyla özellikli telefonlar ve bilgisayarlar arasında iletişim kurulmasını sağlamak için OpenBTS hücresi kullanarak "evrak çantasında" duran felaket iletişimlerinin bir çerçevesini ortaya koydu. Yani operatör kullanmadan telefonla iletişim kurabilirsiniz.

Daha fazla bilgi

WebRTC codelab'i, Node'da çalışan bir Socket.io sinyal hizmetini kullanarak görüntülü ve metinli sohbet uygulamasının nasıl oluşturulacağıyla ilgili adım adım talimatlar sağlar.

WebRTC teknik lideri Justin Uberti ile 2013 tarihli Google I/O WebRTC sunumu

Chris Wilson'ın SFHTML5 sunumu - WebRTC Uygulamalarına Giriş

350 sayfalık WebRTC: API'ler ve HTML5 Gerçek Zamanlı Web'in RTCWEB Protokolleri adlı kitap, veriler ve sinyal yolları hakkında birçok ayrıntı sağlamanın yanı sıra çok sayıda ayrıntılı ağ topolojisi diyagramı da içerir.

WebRTC ve Sinyal: İki Yıl Bize Neler Öğretti? - Sinyali spesifikasyonların dışında bırakmanın neden iyi bir fikir olduğu hakkındaki TokBox blog yayını

Ben Strong'un A Practical Guide to Building WebRTC Apps (WebRTC Uygulamaları Oluşturmaya Pratik Kılavuzu) WebRTC topolojileri ve altyapısı hakkında birçok bilgi sağlar.

Ilya Grigorik'in Yüksek Performanslı Tarayıcı Ağ İletişimi başlıklı makalenin WebRTC bölümünde, WebRTC mimarisi, kullanım alanları ve performans ayrıntılı bir şekilde ele alınıyor.