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 kurup ödeme yapmayı ve belki de bunu birden fazla veri merkezi için ölçeklendirmeyi gerektirir. 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 oluşturulup kullanılacağına dair temel bilgilerin yanı sıra günümüzde web'de yaygın olarak kullanılan kullanım örnekleri ele alınmaktadır.

Neden başka bir veri kanalı tercih etmelisiniz?

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, gecikmenin daha düşük olmasına, yani ara sunucu olmamasına ve daha az "atlamaya" neden olabilir.
  • 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 sinyalleşme sunucularına ihtiyaç duyar.

WebRTC, NAT'ler ve güvenlik duvarlarıyla aşağıdaki özelliklere sahiptir:

  • Benzerler arasında mümkün olan en iyi ağ yolunu oluşturmaya yönelik ICE çerçevesi.
  • Her eş için herkes tarafından erişilebilen IP ve bağlantı noktasını belirlemek üzere STUN sunucuları.
  • Doğrudan bağlantı başarısız olursa ve veri geçişi gerekiyorsa sunucuları DÖN.

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. RTCDataChannel, dizelerin yanı sıra JavaScript'teki Blob, ArrayBuffer ve ArrayBufferView gibi bazı ikili program türlerini de destekler. Bu türler dosya aktarımı ve çok oyunculu oyunlarda yararlı 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 işlem daha fazla ek yük gerektirdiğinden bu mod daha yavaş olabilir.
  • Güvenilir olmayan ve sırasız mod, her mesajın diğer tarafa veya hangi sırayla gönderileceğine dair garanti vermez. Böylece ek yük 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, kayıp bir paket diğer paketlerin arkasında engellenmesine neden olur ve kayıp paket, yeniden iletip yerine ulaşana kadar eskimiş 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
TeslimatSipariş verildiSırasızYapılandırılabilir
BulaşmaBayt odaklıMesaj odaklıMesaja dayalı
Akış denetimiEvetHayırEvet
Tıkanıklık 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 internette birkaç basit demosu vardır:

Bu örneklerde tarayıcı, 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 iletiniz, 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
};

Bir maxRetransmits seçeneği de (başarısız olmadan önce denenecek sayı) eklenebilir ancak maxRetransmits veya maxPacketLifeTime değerini belirtebilirsiniz. Her ikisini birden belirtemezsiniz. 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 mesajı 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 izin verir
  • negotiated: true olarak ayarlanırsa diğer eş tarafta otomatik olarak veri kanalı oluşturma işlemi kaldırılır ve diğer tarafta aynı kimliğe sahip bir veri kanalı oluşturmak için kendi yönteminizi kullanabilirsiniz.
  • id: Yalnızca true olarak ayarlanmış negotiated ile birlikte kullanılabilecek kanal için kendi kimliğinizi sağlamanıza olanak tanır.

Ç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 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şlenkten 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üşüncenizi değiştirin

Büyük miktarlarda veri işlemek JavaScript'te sorunlu 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. Birazdan göreceğiniz gibi FileSystem API gibi teknolojiler burada 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ında bağlantı kurun.
  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 ölçüde küçükse ve bir Blob olarak depolanıp yüklenebiliyorsa, File API'yi kullanarak belleğe yükleyebilir ve daha sonra dosyayı olduğu gibi güvenilir bir kanal üzerinden gönderebilirsiniz (yine de tarayıcıların maksimum aktarım boyutuna sınırlar getirdiğini 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 işlem sırasında, 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ğu için 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 KiB'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 geliştirmenin yeni yollarının kapılarını açıyor.

  • 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 uygulamasının uygulanmasını kolaylaştırır ve API, artık platformlarda geniş bir desteğe sahiptir.

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

Daha fazla bilgi