跪拜 Guibai
← All articles
Rust · WebRTC · WebAssembly

How a Browser Pulls Off Peer-to-Peer File Transfers Without a File System or Listening Port

By 红尘散仙 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

A browser-based P2P transfer tool that hits native speeds removes the last reason to install a separate app for cross-device file sharing, especially on locked-down machines. The architecture demonstrates that a single Rust core can drive desktop, mobile, and wasm targets without duplicating protocol logic, and the hard-won lessons around certificate rotation, secure context failures, and SCTP throughput limits are directly applicable to anyone building real-time browser applications.

Summary

A browser tab can now send and receive files directly between devices, no install required, matching the experience of native tools like LocalSend but working across networks. SwarmDrop achieves this by pairing three browser capabilities that were never designed to work together: WebRTC for NAT traversal and initial contact, WebTransport for a 4.5x faster same-network path, and the Origin Private File System for persistent, seekable on-disk storage that makes resumable transfers possible. The same Rust core runs across desktop, mobile, and browser, with platform I/O abstracted behind a handful of interface methods.

The WebTransport integration delivered a median throughput of 322 MiB/s in loopback tests, up from 72 MiB/s over WebRTC, while collapsing speed fluctuation from a 6.6x range to ±7%. On real hardware, a phone pushing to a browser over LAN hits roughly 20 MB/s, putting the browser's receive path on par with native QUIC between two devices. The send direction lags at about 9 MB/s because wasm's single-threaded file reads and checksum computation cannot yet overlap with network writes.

Several sharp edges emerged during development. WebTransport's self-signed certificates expire after 14 days, forcing a dual-certificate rotation strategy that doubles address lifespan to 28 days. The secure context requirement silently disables OPFS and Web Crypto when a page loads over plain HTTP to a private IP like 192.168.x.x, causing writes to hang forever with no error. And WebRTC's SCTP-based DataChannel, optimized for low-latency signaling rather than throughput, remains the only option for cross-network transfers because WebTransport still lacks a NAT traversal mechanism.

Takeaways
WebRTC handles NAT traversal and initial signaling but tops out around 72 MiB/s with 6.6x speed fluctuation on the same machine.
WebTransport over QUIC raises same-machine throughput to 322 MiB/s and narrows fluctuation to ±7%, but lacks any NAT hole-punching mechanism.
OPFS provides a real file system inside the browser sandbox with seekable writes, enabling resumable transfers without holding entire files in memory.
Self-signed WebTransport certificates expire after 14 days, requiring a rolling dual-certificate strategy so addresses remain valid across rotation boundaries.
Loading a page over HTTP to a private IP (192.168.x.x) silently disables OPFS and Web Crypto, causing writes to hang indefinitely with no error or timeout.
Browser-to-phone send speed is roughly half of receive speed because wasm file reads and checksum computation are single-threaded and cannot overlap with network I/O.
Resumable transfers work for receiving but not sending in the browser, since File objects from <input> do not survive a page refresh.
The same Rust core runs across Tauri, React Native, and wasm targets; only platform I/O implementations differ.
Conclusions

WebTransport's 14-day certificate limit is the kind of constraint that looks like a footnote but reshapes the entire address distribution model, forcing a time dimension onto something that was previously static config.

A Promise that hangs forever because the API object is undefined is a worse failure mode than an exception; the secure context trap on private IPs will waste days for anyone who hits it without knowing to check isSecureContext first.

WebRTC's SCTP layer is optimized for signaling latency, not bulk throughput, which means any browser app moving large files over DataChannel will hit a hard ceiling that no amount of JS tuning can fix.

Keeping the browser send path non-resumable is the correct call: restoring a session that can't reopen its source file produces a progress bar that can never finish, which is worse than starting over.

The 4.5x speedup from WebTransport matters less than the collapse in variance; users perceive a stable 300 MiB/s as dramatically faster than a connection averaging the same speed but swinging between 44 and 288.

Concepts & terms
WebRTC
A browser API and protocol stack that enables direct peer-to-peer communication between devices behind NATs. It handles NAT traversal via ICE, encrypts via DTLS, and multiplexes streams via SCTP. Its DataChannel is optimized for low-latency signaling, not bulk data throughput.
WebTransport
A browser API that exposes QUIC (a UDP-based transport with built-in TLS 1.3 and independent multiplexed streams) to JavaScript. It supports connecting to self-signed certificates via certificate hashes, avoiding the need for a CA-signed domain, but lacks NAT traversal.
OPFS (Origin Private File System)
A sandboxed, persistent file system available per origin in modern browsers. Unlike IndexedDB, it supports seekable random writes, making it suitable for large files and resumable transfers. Access requires a secure context (HTTPS or localhost).
Secure Context
A browser security model that gates sensitive APIs (OPFS, Web Crypto) behind HTTPS, localhost, or loopback addresses. Plain HTTP to a private IP like 192.168.x.x is not a secure context, and restricted APIs silently return undefined rather than throwing errors.
NAT Traversal / Hole-Punching
A technique where two devices behind NAT routers simultaneously send packets to each other's public mapped addresses. Each outbound packet creates a temporary mapping on the sender's router, allowing the other's inbound packet to pass through when it arrives.
SCTP (Stream Control Transmission Protocol)
A transport-layer protocol that provides reliable, ordered delivery with native multiplexing of independent streams. WebRTC uses it under DataChannel, but browser implementations run in user space and are tuned for small real-time messages rather than high-throughput file transfers.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗