WebRTC veri kanallarıyla tarayıcılar arasında veri gönderme

İletişim, oyun veya dosya aktarımı için iki tarayıcı arasında veri göndermek oldukça karmaşık bir işlem olabilir. Verileri aktarmak için bir sunucu oluşturmanız ve bunun için ödeme yapmanız, hatta bunu birden fazla veri merkezine ölçeklendirmeniz gerekir. Bu senaryoda gecikme süresi yüksek olabilir ve verilerin gizli kalması zordur.

Bu sorunlar, verileri doğrudan bir eşe diğerinden aktarmak için WebRTC'nin RTCDataChannel API'si kullanılarak azaltılabilir. Bu makalede, veri kanallarının nasıl ayarlanacağı ve kullanılacağıyla ilgili temel bilgiler ve günümüzde web'de yaygın olarak kullanılan kullanım alanları ele alınmaktadır.

Neden başka bir veri kanalı?

WebSocket, AJAX ve Sunucu Tarafından Gönderilen Etkinlikler'i kullanıyoruz. Why do we need another communication channel? WebSocket iki yönlüdür ancak bu teknolojilerin tümü bir sunucuyla iletişim için tasarlanmıştır.

RTCDataChannel ise farklı bir yaklaşım benimser:

  • Eşler arası bağlantıyı sağlayan RTCPeerConnection API ile çalışır. Bu, gecikme süresinin azalmasına neden olabilir. Ara sunucu olmadığından ve daha az "atlama" olduğundan gecikme süresi azalır.
  • RTCDataChannel, Stream Control Transmission Protocol (SCTP) kullanır. Bu protokol, yapılandırılabilir yayın semantikleri, sıra dışı yayın ve yeniden yayın yapılandırmasına olanak tanır.

RTCDataChannel artık masaüstünde ve Android'de Google Chrome, Opera ve Firefox'ta SCTP desteğiyle kullanılabilir.

Uyarı: Sinyal, STUN ve TURN

WebRTC, eşler arası iletişimi sağlar ancak eşler arası bağlantıyı başlatmak için medya ve ağ meta verilerini paylaşmak üzere sinyal verme için yine de sunuculara ihtiyaç duyar.

WebRTC, NAT'ler ve güvenlik duvarlarıyla aşağıdakiler sayesinde başa çıkabilir:

  • Eşler arasında mümkün olan en iyi ağ yolunu oluşturmak için ICE çerçevesi.
  • Her eş için herkese açık bir IP ve bağlantı noktası belirlemek üzere STUN sunucuları.
  • Doğrudan bağlantı başarısız olursa ve veri aktarımı gerekiyorsa TURN sunucuları.

WebRTC'nin sinyal ve ağ oluşturma için sunucularla nasıl çalıştığı hakkında daha fazla bilgi için Gerçek dünyada WebRTC: STUN, TURN ve sinyal başlıklı makaleyi inceleyin.

Özellikler

RTCDataChannel API, esnek bir veri türü grubunu destekler. API, WebSocket'i tam olarak taklit edecek şekilde tasarlanmıştır ve RTCDataChannel, Blob, ArrayBuffer ve ArrayBufferView gibi JavaScript'teki bazı ikili türlerin yanı sıra dizeleri de destekler. Bu tür bağlantılar, dosya aktarımı ve çok oyunculu oyunlarda faydalı olabilir.

RTCDataChannel, güvenilir olmayan ve sırasız modda (Kullanıcı Datagram Protokolü veya UDP'ye benzer), güvenilir ve sıralı modda (Gönderim Kontrol Protokolü veya TCP'ye benzer) ve kısmen güvenilir modlarda çalışabilir:

  • Güvenilir ve sıralı mod, iletilerin iletilmesini ve teslim edilme sırasını garanti eder. Bu, ek iş yükü gerektirir ve bu modu daha yavaş hale getirebilir.
  • Güvenilir olmayan ve sırasız mod, her ileti için diğer tarafa ulaşmayı veya iletilerin hangi sırayla ulaşacağını garanti etmez. Bu sayede ek maliyetler ortadan kalkar ve bu mod çok daha hızlı çalışır.
  • Kısmi güvenilir mod, iletilerin belirli bir koşul altında (ör. yeniden iletim zaman aşımı veya maksimum yeniden iletim sayısı) iletilmesini garanti eder. Mesajların sıralaması da yapılandırılabilir.

Paket kaybı olmadığında ilk iki modun performansı yaklaşık olarak aynıdır. Ancak güvenilir ve sıralı modda, kaybolan bir paket diğer paketlerin engellenmesine neden olur ve kaybolan paket yeniden gönderilip gelene kadar eski olabilir. Elbette aynı uygulamada, her biri kendi güvenilir veya güvenilir olmayan semantiklerine sahip birden fazla veri kanalı kullanmak mümkündür.

Ilya Grigorik tarafından yazılan Yüksek Performanslı Tarayıcı Ağları kitabından faydalı bir tabloyu aşağıda bulabilirsiniz:

TCPUDPSCTP
GüvenilirlikGüvenilirGüvenilir değilYapılandırılabilir
Adrese teslimSipariş verildiSırasızYapılandırılabilir
BulaşmaBayt odaklıMesaja dayalıMesaja dayalı
Akış denetimiEvetHayırEvet
Trafik sıkışıklığı kontrolüEvetHayırEvet

Ardından, RTCDataChannel öğesini güvenilir ve sıralı veya güvenilir olmayan ve sırasız modu kullanacak şekilde nasıl yapılandıracağınızı öğrenirsiniz.

Veri kanallarını yapılandırma

RTCDataChannel'ün birkaç basit demosunu internette bulabilirsiniz:

Bu örneklerde tarayıcı, kendi kendisiyle eş bağlantısı oluşturur, ardından bir veri kanalı oluşturur ve eş bağlantı üzerinden bir mesaj gönderir. Ardından bir veri kanalı oluşturur ve mesajı eş bağlantı üzerinden gönderir. Son olarak, mesajınız sayfanın diğer tarafındaki kutuda görünür.

Bu işlemi başlatmak için gereken kod kısadır:

const peerConnection = new RTCPeerConnection();

// Establish your peer connection using your signaling channel here
const dataChannel =
  peerConnection.createDataChannel("myLabel", dataChannelOptions);

dataChannel.onerror = (error) => {
  console.log("Data Channel Error:", error);
};

dataChannel.onmessage = (event) => {
  console.log("Got Data Channel Message:", event.data);
};

dataChannel.onopen = () => {
  dataChannel.send("Hello World!");
};

dataChannel.onclose = () => {
  console.log("The Data Channel is Closed");
};

dataChannel nesnesi, önceden kurulmuş bir eş bağlantısından oluşturulur. İşaretleme işleminden önce veya sonra oluşturulabilir. Ardından, bu kanalı diğerlerinden ayırt etmek için bir etiket ve isteğe bağlı yapılandırma ayarları gönderirsiniz:

const dataChannelOptions = {
  ordered: false, // do not guarantee order
  maxPacketLifeTime: 3000, // in milliseconds
};

maxRetransmits seçeneği (başarısız olmadan önce deneme sayısı) de ekleyebilirsiniz ancak her ikisini de değil, yalnızca maxRetransmits veya maxPacketLifeTime'ı belirtebilirsiniz. UDP semantiği için maxRetransmits değerini 0, ordered değerini ise false olarak ayarlayın. Daha fazla bilgi için şu IETF RFC'lerine bakın: Stream Control Transmission Protocol ve Stream Control Transmission Protocol Partial Reliability Extension.

  • ordered: Veri kanalının sırayı garanti etmesi gerekip gerekmediği
  • maxPacketLifeTime: Başarısız bir mesajı yeniden göndermeyi denemek için azami süre
  • maxRetransmits: Başarısız bir iletiyi yeniden göndermeyi denemek için kullanılacak maksimum deneme sayısı
  • protocol: Uygulamaya meta bilgiler sağlayan bir alt protokolün kullanılmasına olanak tanır
  • negotiated: true olarak ayarlanırsa diğer eş tarafta otomatik olarak veri kanalı oluşturma işlemi kaldırılır. Böylece, diğer tarafta aynı kimliğe sahip bir veri kanalı oluşturmak için kendi yönteminizi kullanabilirsiniz.
  • id: Kanal için kendi kimliğinizi sağlamanıza olanak tanır. Bu kimlik yalnızca negotiated true olarak ayarlandığında kullanılabilir.

Çoğu kullanıcının kullanması gereken tek seçenekler ilk üç seçenektir: ordered, maxPacketLifeTime ve maxRetransmits. SCTP (artık WebRTC'yi destekleyen tüm tarayıcılar tarafından kullanılır) ile güvenilir ve sıralı varsayılan olarak doğrudur. Uygulama katmanından tam kontrol sahibi olmak istiyorsanız güvenilir olmayan ve sırasız kullanmanın mantığı vardır ancak çoğu durumda kısmi güvenilirlik faydalıdır.

WebSocket'te olduğu gibi, RTCDataChannel'ün de bağlantı kurulduğunda, kapatıldığında veya hata oluştuğunda ve diğer eşten mesaj aldığında etkinlik tetiklediğini unutmayın.

Bu, güvenli mi?

Şifreleme, tüm WebRTC bileşenleri için zorunludur. RTCDataChannel ile tüm veriler Datagram Taşıma Katmanı Güvenliği (DTLS) ile güvence altına alınır. DTLS, SSL'nin türevidir. Bu, verilerinizin standart SSL tabanlı bağlantılar kadar güvenli olacağı anlamına gelir. DTLS standarttır ve WebRTC'yi destekleyen tüm tarayıcılara yerleştirilmiştir. Daha fazla bilgi için Wireshark wiki sayfasına bakın.

Veriler hakkındaki düşüncelerinizi değiştirme

Büyük miktarlarda veri işlemek JavaScript'te sorunlu bir konu olabilir. Sharefest'in geliştiricileri, bunun için verileri yeni bir şekilde düşünmeleri gerektiğini belirtiyor. Mevcut bellek miktarınızdan daha büyük bir dosya aktarıyorsanız bu bilgileri kaydetmenin yeni yollarını düşünmeniz gerekir. Aşağıda göreceğiniz gibi, bu noktada FileSystem API gibi teknolojiler devreye girer.

Dosya paylaşım uygulaması oluşturma

RTCDataChannel ile artık tarayıcıda dosya paylaşabilen bir web uygulaması oluşturabilirsiniz. RTCDataChannel'ü temel almak, aktarılan dosya verilerinin şifrelendiği ve uygulama sağlayıcının sunucularına dokunmadığı anlamına gelir. Bu işlev, daha hızlı paylaşım için birden fazla istemciye bağlanma olanağıyla birlikte WebRTC dosya paylaşımını web için güçlü bir aday haline getirir.

Başarılı bir aktarım yapmak için birkaç adım gerekir:

  1. File API'yi kullanarak JavaScript'de dosya okuma
  2. RTCPeerConnection ile istemciler arasında eşler arası bağlantı oluşturun.
  3. RTCDataChannel ile müşteriler arasında veri kanalı oluşturun.

RTCDataChannel üzerinden dosya göndermeye çalışırken dikkate alınması gereken birkaç nokta vardır:

  • Dosya boyutu: Dosya boyutu makul derecede küçükse ve tek bir Blob olarak depolanıp yüklenebilirse File API'yi kullanarak dosyayı belleğe yükleyebilir ve ardından dosyayı olduğu gibi güvenilir bir kanal üzerinden gönderebilirsiniz (ancak tarayıcıların maksimum aktarım boyutu için sınırlar uyguladığını unutmayın). Dosya boyutu büyüdükçe işler daha da karmaşık hale gelir. Parçalara ayırma mekanizması gerektiğinde dosya parçaları yüklenir ve diğer eşe gönderilir. Bu sırada, eşin dosyaları tanıyabilmesi için chunkID meta verileri de gönderilir. Bu durumda, parçaları önce çevrimdışı depolamaya (örneğin, FileSystem API'yi kullanarak) kaydetmeniz ve yalnızca dosyanın tamamını aldığınızda kullanıcının diskine kaydetmeniz gerektiğini unutmayın.
  • Gruptaki veri boyutu: Bunlar, uygulamanız için en küçük veri "atomlarıdır". Şu anda bir gönderme boyutu sınırı olduğundan gruplandırma gereklidir (ancak bu, veri kanallarının gelecekteki bir sürümünde düzeltilecektir). Maksimum parça boyutu için geçerli öneri 64 KB'tır.

Dosya diğer tarafa tamamen aktarıldıktan sonra bir ankraj etiketi kullanılarak indirilebilir:

function saveFile(blob) {
  const link = document.createElement('a');
  link.href = window.URL.createObjectURL(blob);
  link.download = 'File Name';
  link.click();
};

PubShare ve GitHub'taki bu dosya paylaşım uygulamaları bu tekniği kullanır. Her ikisi de açık kaynaktır ve RTCDataChannel tabanlı bir dosya paylaşım uygulaması için iyi bir temel sağlar.

Peki ne yapabilirsiniz?

RTCDataChannel, dosya paylaşımı, çok oyunculu oyunlar ve içerik yayınlama için uygulama oluşturmanın yeni yollarını açar.

  • Daha önce açıklandığı gibi eşler arası dosya paylaşımı
  • Mozilla'nın BananaBread oyununda görüldüğü gibi, WebGL gibi diğer teknolojilerle birlikte çok oyunculu oyunlar
  • Web öğelerini eşler arası veri iletişimi aracılığıyla yayınlayan bir çerçeve olan PeerCDN tarafından yeniden keşfedilen içerik yayınlama

Uygulama geliştirme şeklinizi değiştirme

Artık RTCDataChannel üzerinden yüksek performanslı, düşük gecikmeli bağlantılar kullanarak daha ilgi çekici uygulamalar sunabilirsiniz. PeerJS ve PubNub WebRTC SDK'sı gibi çerçeveler, RTCDataChannel'in uygulanmasını kolaylaştırır ve API artık platformlar genelinde geniş destek görmektedir.

RTCDataChannel'ün kullanıma sunulması, tarayıcıda veri aktarımı hakkındaki düşüncelerinizi değiştirebilir.

Daha fazla bilgi