İçeriğe atla
HexaTransfer
Bloga dön
Teknik incelemeler

WebRTC Dosya Transferi: Browser-to-Browser Eğitim

WebRTC kullanarak dosyaları tarayıcılar arasında doğrudan transfer edin. Gerçek zamanlı dosya paylaşımı için veri kanalları, sinyalizasyon ve peer bağlantı kurulumu.

WebRTC dosya transferi, baytları iki tarayıcı arasında RTCDataChannel kullanarak doğrudan taşır; ilk el sıkışmanın ardından veri yolunda hiçbir sunucu yer almaz. İhtiyacınız olan bileşenler: SDP teklifleri ve ICE adaylarını değiştirmek için bir sinyalizasyon kanalı (WebSocket veya küçük bir röle), NAT keşfi için STUN sunucuları, simetrik NAT'lar için TURN yedeği ve güvenilir sıralı iletim için yapılandırılmış bir veri kanalı. Peer bağlantısı kurulunca channel.send() ile 16 KB-256 KB'lık parçalar gönderin; baytlar DTLS 1.2 şifreli SCTP ilişkisi üzerinden yaklaşık ağ hızında akar.

WebRTC'nin Gerçekte Eşler Arası Bağlantıyı Nasıl Sağladığı

WebRTC sihir değildir — ICE artı SDP artı DTLS artı SCTP yığını. Gönderici bir RTCPeerConnection oluşturur, veri kanalı açar, SDP teklifi üretir ve sinyalizasyon kanalı aracılığıyla alıcıya gönderir. Alıcı yanıt verir. Her iki taraf da çalışan bir yol bulana kadar ICE adaylarını (yerel IP, STUN aracılığıyla reflektif IP, TURN aracılığıyla röle IP) değiştirir. DTLS 1.2 uçtan uca el sıkışır, SCTP güvenilir akış için üstte çalışır ve baytlar akmaya başlar.

Şifreleme zorunlu ve yerleşiktir, devre dışı bırakamazsınız. Bu anlamlı bir güvenlik kazanımıdır — WebSocket'in aksine, ağ dinleyicilerine karşı koruma için uygulama katmanı kripto sarmayı hatırlamanız gerekmez. Kendi sinyalizasyon sunucunuza karşı gerçek E2EE için ek bir AES-256-GCM katmanı ekleyin; çünkü kötü niyetli bir sinyalizasyon sunucusu kendi DTLS sertifikasını değiştirebilir.

Sinyalizasyon: WebRTC'nin Tanımlamadığı Kısım

WebRTC kasıtlı olarak sinyalizasyonu size bırakır. Sunucunuzdaki bir WebSocket kullanışlıdır; Firebase gerçek zamanlı DB'ye gönderilen paylaşılan oda kodu veya elle yapıştırılan SDP dizeleri de işe yarar. Önemli olan her iki eşin sonunda bir teklif, bir yanıt ve bir ICE aday akışı değiştirmesidir.

Node.js'te minimal sinyalizasyon sunucusu:

const rooms = new Map();
wss.on('connection', (ws) => {
  ws.on('message', (raw) => {
    const msg = JSON.parse(raw);
    if (msg.type === 'join') {
      const room = rooms.get(msg.room) ?? new Set();
      room.add(ws); rooms.set(msg.room, room);
    } else {
      for (const peer of rooms.get(msg.room) ?? []) {
        if (peer !== ws) peer.send(raw);
      }
    }
  });
});

20 satırın altında. Sunucu dosya baytlarını asla görmez — yalnızca SDP ve ICE metadata'sını. Bunu 5 USD'lik VPS veya Cloudflare Workers üzerinde barındırabilir ve yüzlerce eş zamanlı transfere hizmet verebilirsiniz.

Peer Bağlantısını Kurma

Bağlantıyı Google'ın genel STUN sunucusu ve TURN yedeğiyle oluşturun:

const pc = new RTCPeerConnection({
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' },
    { urls: 'turn:turn.example.com:3478',
      username: 'user', credential: 'pass' }
  ]
});

Konut bağlantılarının yaklaşık %15-25'i STUN'un geçemediği simetrik NAT'ların arkasındadır; bu nedenle TURN üretim servisi için zorunludur. Yeterli bant genişliğine sahip VPS üzerinde coturn çalıştırın veya Xirsys ya da Twilio gibi yönetilen TURN sağlayıcısı için ödeme yapın.

Veri kanalını teklif oluşturmadan önce teklifçi tarafında açın:

const channel = pc.createDataChannel('file', {
  ordered: true, maxRetransmits: null
});
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send({ type: 'offer', sdp: offer.sdp });

Sıralı + sınırsız yeniden iletim TCP eşdeğeri güvenilirlik sağlar. Sırasız mod daha hızlıdır ancak uygulama düzeyinde yeniden montaj gerektirir.

Kanal İçin Dosyayı Parçalama

SCTP'nin pratik mesaj başına 256 KB sınırı vardır; eski tarayıcılar 16 KB'ın üzerinde zorlanır. File.slice() aracılığıyla dosyadan okunan 16 KB parça güvenli bir varsayılandır:

const chunkSize = 16 * 1024;
let offset = 0;
channel.bufferedAmountLowThreshold = 1024 * 1024;
function sendNext() {
  while (offset < file.size && channel.bufferedAmount < 4 * 1024 * 1024) {
    const chunk = file.slice(offset, offset + chunkSize);
    chunk.arrayBuffer().then((buf) => channel.send(buf));
    offset += chunkSize;
  }
}
channel.onbufferedamountlow = sendNext;
sendNext();

bufferedAmount filigranı gigabaytları SCTP'nin gönderme arabelleğine kuyruğa sokmayı ve bellek tükenmesini önler. Arabellek 1 MB'ın altına düştüğünde 4 MB'a kadar yeniden doldurun. Bu, yerel ağlarda 40-80 MB/s ve tipik konut genişbandında 5-20 MB/s'e yakın aktarım hızı sağlar.

Alıcı Tarafta Baytları Okuma ve Diske Yazma

Yanıt veren tarafta gelen kanalı dinleyin:

pc.ondatachannel = ({ channel }) => {
  const chunks = [];
  let received = 0;
  channel.onmessage = ({ data }) => {
    chunks.push(data);
    received += data.byteLength;
    updateProgress(received);
    if (received === expectedSize) finish(chunks);
  };
};

500 MB'ın üzerindeki dosyalar için RAM'de biriktirmeyin. Doğrudan diske akıtmak için File System Access API kullanın:

const handle = await window.showSaveFilePicker({ suggestedName: fileName });
const writable = await handle.createWritable();
channel.onmessage = async ({ data }) => writable.write(data);

Firefox ve Safari henüz showSaveFilePicker'ı desteklemiyor; bu tarayıcılar için Blob + URL.createObjectURL indirme yedeğine dönün, 2 GB ile sınırlı.

Baytlardan Önce Dosya Metadata'sını Gönderme

Alıcının bayt akışı başlamadan önce dosya adını, boyutunu ve MIME türünü bilmesi gerekir. Veri kanalında küçük bir JSON el sıkışması kullanın:

channel.send(JSON.stringify({
  type: 'metadata', name: file.name,
  size: file.size, mime: file.type, sha256: fileHash
}));

Ardından ikili moda geçin. Alıcı data'nın string mi yoksa ArrayBuffer mu olduğuna göre geçiş yapar. Transfer sonrası bütünlük doğrulaması için dosyanın SHA-256'sını ekleyin; uygulama düzeyinde AES-GCM katmanlıyorsanız isteğe bağlı olarak anahtar parmak izini de ekleyin.

Bağlantı Hatalarıyla Başa Çıkma

WebRTC veri kanalları üç şekilde başarısız olur: ICE hiç tamamlanmaz (NAT, güvenlik duvarı engeli), DTLS el sıkışması başarısız olur (saat kayması, sertifika sorunları) veya bağlantı transfer ortasında düşer (dizüstü bilgisayar uyku modu, ağ değişimi). pc.oniceconnectionstatechange dinleyin ve 'failed' veya 'disconnected''a göre hareket edin. Chrome, 'failed''a geçmeden önce 'disconnected''ı birkaç saniye tutar; Safari daha az sabırlıdır.

Transfer ortasında başarısız olduğunda tüm bağlantıyı yeniden oluşturmadan ICE'ı yeniden başlatın:

await pc.restartIce();
const offer = await pc.createOffer({ iceRestart: true });
// sinyalizasyon üzerinden yeniden gönderin

Yeniden başlatma başarısız olursa sunucunuz üzerinden sürdürülebilir yüklemeye geri dönün — karma P2P + sunucu mimarisi. Wormhole ve justbeamit gibi bazı WebRTC transfer araçları bu deseni kullanır çünkü saf P2P'nin çalışamadığı ağ koşullarının %15'ini yönetir.

Kendi Sunucunuza Karşı Uçtan Uca Şifreleme Ekleme

WebRTC'nin yerleşik DTLS'i ağ saldırganlarına karşı korur, ancak kötü niyetli veya ele geçirilmiş sinyalizasyon sunucusuna karşı değil. Gerçek E2EE için her iki eşin ECDH P-256 anahtar çifti oluşturmasını, açık anahtarları kısa bant dışı kod (QR veya 6 kelimelik parola ifadesi) üzerinden değiştirmesini, HKDF-SHA256 aracılığıyla paylaşılan sır türetmesini ve send çağrısından önce her veri kanalı mesajını AES-256-GCM ile şifrelemesini sağlayın. Bu sayede sinyalizasyon sunucusu DTLS sertifikalarını değiştirse bile dosyalarınızı okuyamaz.

HexaTransfer karma mimari kullanır — P2P yerine sunucu tarafında depolanan şifreli metin ile istemci tarafında AES-256-GCM — çevrimdışı toleranslı paylaşım için doğrudanlıktan fedakarlık eder. hexatransfer.com'da deneyin — ücretsiz, hesap gerekmez, maksimum 10 GB.

WebRTC'nin Kazandığı ve Kaybettiği Durumlar

WebRTC dosya transferi her iki eş de eş zamanlı çevrimiçi olduğunda, kendi sunucunuzdan gizlilik önemli olduğunda ve dosyalar röle bant genişliği maliyetinin ağır olacağı kadar büyük olduğunda (100 MB+) üstündür. Kullanıcıların gönderip ayrılmak istediğinde, alıcıların bağlantıyı saatler sonra açtığında veya alıcıların STUN ve TURN'ü engelleyen kısıtlayıcı kurumsal ağlarda olduğunda kaybeder. Genel amaçlı transfer aracı için saf P2P kullanım senaryolarının yaklaşık %60'ını rahatça karşılar. Diğer %40'ın sunucu destekli yedeğe ihtiyacı var — bu nedenle neredeyse her "P2P dosya transferi" ürününün mimarisinde bir yerde röle bulunur.

Uçtan uca şifreleme ile büyük dosyaları güvenle gönderin

Uçtan uca şifreleme ile 10 GB'a kadar dosya ücretsiz aktarın. Hesap gerekmez. Dosyalarınız yüklenmeden önce tarayıcınızda şifrelenir — başka kimse okuyamaz.

Dosya gönder