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 karmaşık bir süreç olabilir. Veri aktarmak için bir sunucunun kurulması ve bunun için ödeme yapılması ve belki de bunu birden fazla veri merkezine ölçeklendirmeniz gerekir. Bu senaryoda yüksek gecikme potansiyeli vardır ve verilerin gizli tutulması zordur.

Verileri doğrudan bir eşten diğerine aktarmak için WebRTC'nin RTCDataChannel API'sini kullanarak bu sorunlar hafifletilebilir. Bu makalede, veri kanallarının nasıl oluşturulup kullanılacağına dair temel bilgilerin yanı sıra bugün web'de yaygın kullanım alanları ele alınmaktadır.

Neden başka bir veri kanalı?

WebSocket, AJAX ve Server Sent Event'i (Sunucu Gönderilen Etkinlikler) kullandık. Neden başka bir iletişim kanalına ihtiyacımız var? WebSocket çift yönlüdür, ancak tüm bu teknolojiler bir sunucuyla veya sunucudan iletişim için tasarlanmıştır.

RTCDataChannel farklı bir yaklaşım benimsiyor:

  • Eşler arası bağlantı sağlayan RTCPeerConnection API ile birlikte çalışır. Bu, daha düşük gecikmeyle sonuçlanabilir (ara sunucu yoktur ve daha az "atlama").
  • RTCDataChannel, Akış Denetimi İletim Protokolü'nü (SCTP) kullanır. Böylece, yapılandırılabilir dağıtım semantiği, sıra dışı dağıtım ve yeniden iletim yapılandırmasına izin verir.

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

Dikkat: Sinyal, STUN ve DÖNÜŞ

WebRTC, eşler arası iletişimi etkinleştirir ancak sinyal ile medya ve ağ meta verilerini değiş tokuş ederek bir eşler arası bağlantıyı önyükleyebilmek için sunuculara ihtiyaç duyar.

WebRTC, şunlarla NAT'ler ve güvenlik duvarları ile başa çıkabilir:

  • Eşler arasında mümkün olan en iyi ağ yolunu oluşturmaya yönelik ICE çerçevesi.
  • STUN sunucularını kullanarak her eş için herkese açık bir IP ve bağlantı noktası belirleyin.
  • Doğrudan bağlantı başarısız olursa ve veri geçişi gerekiyorsa TURN sunucuları.

WebRTC'nin sinyal ve ağ iletişimi için sunucularla nasıl çalıştığı hakkında daha fazla bilgi edinmek üzere Gerçek dünyada WebRTC: STUN, TURN ve sinyal oluşturma 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 ise dizelerin yanı sıra JavaScript'teki Blob, ArrayBuffer ve ArrayBufferView gibi bazı ikili program türlerini destekler. Bu türler, dosya aktarımı ve çok oyunculu oyunlarda çalışırken faydalı olabilir.

RTCDataChannel, güvenilir olmayan ve sırasız modda (Kullanıcı Datagram Protokolü'ne veya UDP'ye benzer), güvenilir ve sıralı modda (İletim Denetimi Protokolü'ne veya TCP'ye benzer) ve kısmi güvenilir modlarda çalışabilir:

  • Güvenilir ve sıralı mod, mesajların iletilmesini ve teslim edilme sırasını garanti eder. Bu işlem ek yük gerektirdiğinden bu modun yavaşlamasına neden olabilir.
  • Güvenilir olmayan ve sırasız mod, her mesajın diğer tarafa ulaşmasını veya mesajın hangi sırada gösterileceğini garanti etmez. Bu, ek yükü ortadan kaldırarak bu modun çok daha hızlı çalışmasını sağlar.
  • Kısmi güvenilir mod, yeniden iletim zaman aşımı veya maksimum yeniden iletim sayısı gibi belirli bir koşul altında iletinin iletimini garanti eder. İletilerin sırası da yapılandırılabilir.

İlk iki modun performansı, paket kaybı olmadığında 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 iletilip ulaştığında eski olabilir. Elbette, aynı uygulama içinde her biri kendi güvenilir veya güvenilir olmayan semantiğine sahip birden fazla veri kanalı kullanmak mümkündür.

Ilya Grigorik'in High Performance Scanner Networking (Yüksek Performanslı Tarayıcı Ağ İletişimi) başlıklı videoda yer alan faydalı bir tablosu aşağıda verilmiştir:

TCPUDPSCTP
GüvenilirlikGüvenilirGüvenilir değilYapılandırılabilir
Adrese teslimSipariş verildiSıralanmamışYapılandırılabilir
BulaşmaBayt odaklıMesaj odaklıMesaj odaklı
Akış denetimiEvetHayırEvet
Tıkanıklık kontrolüEvetHayırEvet

Şimdi de RTCDataChannel adlı cihazı güvenilir ve sıralı ya da güvenilir olmayan ve sırasız modu kullanacak şekilde nasıl yapılandıracağınızı öğreneceksiniz.

Veri kanallarını yapılandırma

İnternette RTCDataChannel için birkaç basit demo bulabilirsiniz:

Bu örneklerde, tarayıcı kendisiyle bir eş bağlantısı oluşturur, ardından bir veri kanalı oluşturur ve eş bağlantısı üzerinden bir ileti gönderir. Bu işlemin ardından bir veri kanalı oluşturulur ve iletiyi eş bağlantısı üzerinden gönderir. Son olarak, iletiniz sayfanın diğer tarafındaki kutuda görünür.

Başlamak 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ıdan oluşturulur. Sinyal olmadan önce veya sonra oluşturulabilir. Daha sonra, bu kanalı diğerlerinden ayırt etmek için bir etiket ve bir dizi isteğe bağlı yapılandırma ayarı eklersiniz:

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

Ayrıca, bir maxRetransmits seçeneği (başarısız olmadan önce denenecek sayısı) eklemek de mümkündür, ancak yalnızca maxRetransmits veya maxPacketLifeTime değerlerini belirtebilirsiniz, ikisini birden belirtemezsiniz. UDP semantiği için maxRetransmits değerini 0 ve ordered değerini false olarak ayarlayın. Daha fazla bilgi için şu IETF RFC'lerine bakın: Stream Control Transmission Protocol ve Stream Control Transmission Protocol Kısmi Güvenilirlik Uzantısı.

  • ordered: Veri kanalının siparişi garanti etmesi gerekip gerekmediği
  • maxPacketLifeTime: Başarısız bir iletiyi iletmeyi denemek için maksimum süre
  • maxRetransmits: Başarısız bir iletiyi göndermenin maksimum deneme sayısı
  • protocol: Uygulamaya yönelik meta bilgiler sağlayan alt protokolün kullanılmasına izin verir
  • negotiated: Doğru değerine ayarlanırsa diğer benzerdeki veri kanalının otomatik kurulumunu kaldırır. Bu sayede, diğer tarafta aynı kimliğe sahip veri kanalı oluşturmak için kendi yönteminizi sağlarsınız
  • id: Kanal için kendi kimliğinizi sağlamanıza olanak tanır. Bu kimlik yalnızca true olarak ayarlanmış negotiated ile birlikte kullanılabilecektir.

Çoğu kullanıcı yalnızca ilk üç seçeneği kullanır: ordered, maxPacketLifeTime ve maxRetransmits. SCTP (artık WebRTC'yi destekleyen tüm tarayıcılar tarafından kullanılmaktadır) güvenilirdir ve varsayılan olarak doğru sıralanır. Uygulama katmanında tam kontrol sahibi olmak istiyorsanız güvenilir olmayan ve sıralı olmayan reklamları kullanmak mantıklıdır, ancak çoğu durumda kısmi güvenilirlik yararlı olacaktır.

WebSocket'te olduğu gibi, RTCDataChannel ürününün bir bağlantı kurulduğunda, kapatıldığında, hata verdiğinde ve diğer eşten ileti aldığında etkinlikleri tetiklediğini unutmayın.

Bu, güvenli mi?

Tüm WebRTC bileşenleri için şifreleme zorunludur. RTCDataChannel ile tüm verilerin güvenliği Datagram Taşıma Katmanı Güvenliği (DTLS) ile sağlanır. DTLS, SSL'nin bir türevidir. Diğer bir deyişle, verileriniz herhangi bir standart SSL tabanlı bağlantı kadar güvenli olur. DTLS standartlaştırılmıştır ve WebRTC'yi destekleyen tüm tarayıcılarda yerleşiktir. Daha fazla bilgi için Wireshark wiki'sine bakın.

Verilere bakış açınızı değiştirin

Büyük miktarlarda veri işlemek, JavaScript'te sorun yaratabilir. Sharefest geliştiricilerinin de belirttiği gibi, bu durum veriler hakkında yeni bir şekilde düşünmeyi gerektiriyordu. Sahip olduğunuz bellek miktarından daha büyük bir dosya aktarıyorsanız bu bilgileri kaydetmenin yeni yollarını düşünmeniz gerekir. Şimdi göreceğiniz gibi, FileSystem API gibi teknolojiler burada devreye giriyor.

Dosya paylaşım uygulaması oluşturma

Tarayıcıda dosya paylaşabilen bir web uygulaması oluşturmak artık RTCDataChannel ile mümkün. RTCDataChannel temel alınarak geliştirildiğinde, aktarılan dosya verileri şifrelenir ve uygulama sağlayıcının sunucularına dokunmaz. 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 getiriyor.

Havalenin başarılı olması için birkaç adım gerekir:

  1. Dosya API'sini kullanarak bir dosyayı JavaScript'te okuyun.
  2. RTCPeerConnection ile istemciler arasında eşler arasında bağlantı kurun.
  3. RTCDataChannel ile müşteriler arasında bir veri kanalı oluşturun.

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

  • Dosya boyutu: Dosya boyutu makul ölçüde küçükse ve tek Blob halinde depolanıp yüklenebiliyorsa Dosya API'sını kullanarak 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 boyutuna sınırlamalar uyguladığını unutmayın). Dosya boyutu büyüdükçe işler karışır. Yığın oluşturma mekanizması gerekli olduğunda, dosya parçaları yüklenir ve eşin tanıyabilmesi için chunkID meta verileriyle birlikte başka bir eşe gönderilir. Bu durumda, parçaları önce çevrimdışı depolama alanına kaydetmeniz (örneğin, FileSystem API'yi kullanarak) ve yalnızca dosyanın tamamıyla sahip olduğunuzda kullanıcının diskine kaydetmeniz gerektiğini unutmayın.
  • Yığın boyutu: Bunlar, uygulamanız için en küçük veri "atomlarıdır". Şu anda bir gönderme boyutu sınırı bulunduğundan yığın boyutu gereklidir (yine de bu durum, veri kanallarının gelecekteki sürümlerinde düzeltilecektir). Maksimum yığın boyutu için geçerli öneri 64 KiB'tır.

Dosya diğer tarafa tamamen aktarıldıktan sonra bir bağlantı 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'daki bu dosya paylaşım uygulamaları bu tekniği kullanır. İkisi de açık kaynaklıdır ve RTCDataChannel tabanlı bir dosya paylaşım uygulaması için iyi bir temel sunar.

Bu durumda ne yapabilirsiniz?

RTCDataChannel; dosya paylaşımı, çok oyunculu oyunlar ve içerik yayınlama için uygulama geliştirmenin yeni yollarının kapısını açar.

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

Uygulama derleme yönteminizi değiştirin

Artık RTCDataChannel üzerinden yüksek performanslı ve düşük gecikmeli bağlantılar kullanarak daha ilgi çekici uygulamalar sağlayabilirsiniz. PeerJS ve PubNub WebRTC SDK'sı gibi çerçeveler, RTCDataChannel uygulamasının uygulanmasını kolaylaştırır ve API, artık platformlar genelinde kapsamlı bir şekilde desteklemektedir.

RTCDataChannel ürününün icadıyla, tarayıcıdaki veri aktarımıyla ilgili düşünceleriniz değişebilir.

Daha fazla bilgi