Moving a file from a laptop to a phone looks like a two-step job: choose the file, then press send. A dependable transfer actually passes through device discovery, consent, network negotiation, transport, integrity checking, and recovery. Cloud drives hide most of that work by uploading the file to storage first. A WebRTC transfer tries to establish an encrypted path between the two browsers and keep the file off permanent server storage.
This guide follows one transfer from start to finish. It explains what “direct” really means, what STUN and TURN do, why a DataChannel still needs an application protocol, and how refreshes should be handled. The useful question is not whether a product can move a demo file once. It is whether the same product behaves predictably on office Wi-Fi, a mobile hotspot, and an interrupted connection.
What P2P means in a browser
WebRTC is best known for calls, but its RTCDataChannel can carry text and binary data. A sender reads a file in chunks, passes those chunks to the browser, and the receiver reassembles them. The WebRTC transport is encrypted in transit.
P2P describes the relationship between endpoints; it does not promise that every packet avoids third-party infrastructure. When a direct route is available, the browsers exchange packets directly. When a firewall or a restrictive NAT blocks that route, both browsers may connect to a TURN relay. The relay forwards encrypted packets. It can observe addresses, timing, and traffic volume, but the application should never give it readable file contents.
The connection before the transfer
Two browsers need a signaling service to exchange an offer, an answer, and ICE candidates. Signaling introduces the endpoints; it is not the file transport. A sound connection flow also separates a known device from a particular browser session. That distinction is what lets trusted devices reconnect without showing a first-contact approval dialog every time.
- The browser creates or loads a local device identity whose private key stays on the device.
- The user finds the other device through a temporary code, a local discovery view, or a trusted invitation.
- The receiver explicitly approves first contact.
- Both sides exchange candidate routes and attempt connectivity checks.
- The application authenticates the remote identity over the new channel.
- Chat, clipboard, file, and screen features become available only after that check succeeds.
The awkward cases define the protocol: both devices can initiate at once; either page can refresh; Wi-Fi can switch to cellular; a stale answer can arrive after a newer session has started. Each connection attempt needs its own session identifier, and late messages from an older attempt must be ignored.
Direct, STUN, and TURN paths
Most devices sit behind NAT. A laptop knows its private address but usually does not know the public address and port another network can reach. A STUN server reports that public mapping and helps WebRTC test a route. STUN does not carry the file after discovery.
If no candidate pair works, TURN becomes the fallback. Every transferred byte then crosses the relay, so region, capacity, authentication, and abuse controls affect both cost and speed. TURN credentials should be short-lived and scoped. A relay advertised as “unlimited” is not a meaningful engineering guarantee; bandwidth always has a real limit somewhere.
| Path | Job | Carries file data? | Typical result |
|---|---|---|---|
| Direct | Endpoint-to-endpoint transport | No third-party relay | Lowest latency when the networks permit it |
| STUN | Discover a public mapping | No | Helps direct connectivity but cannot guarantee it |
| TURN | Relay when direct checks fail | Yes, still encrypted | Higher reachability with relay cost and latency |
A DataChannel is not a file protocol
A simple sender can call send() until the file is exhausted. That works in a friendly demo and fails under latency. Browser buffers grow, control messages wait behind megabytes of data, memory use rises, and the progress bar may claim work that the receiver has not acknowledged.
A production transfer needs a metadata handshake, bounded chunks, backpressure based on bufferedAmount, receiver acknowledgements, missing-range requests, and an immediate cancel message carrying the transfer ID. Progress should distinguish bytes queued locally, bytes acknowledged by the peer, and a file that has passed final verification. Those are three different facts.
Resume and integrity belong together
A resumable receiver persists the file identity, expected size and digest, and the ranges already written. After reconnecting, it reports only the missing ranges. The sender can then continue instead of replaying the whole file.
A browser normally cannot reopen a user-selected local file after the sender page refreshes. The honest recovery flow asks the sender to choose the source again and verifies that it matches the original transfer. At completion, the receiver calculates a cryptographic digest such as SHA-256. Only a matching digest turns “all chunks arrived” into “file verified.” A digest catches damage and accidental reselection; it does not establish who the sender is, so identity authentication is still required.
Refresh without losing control
People want trusted devices to recover aggressively, but automatic recovery must respect an explicit stop. Store the trust relationship, the current WebRTC session, and feature tasks separately. Reconnecting a trusted laptop is reasonable. Restarting screen capture without a deliberate user action is not.
- Give every attempt a new session ID and discard messages from superseded sessions.
- Resolve simultaneous offers with a deterministic role rule instead of maintaining two competing peer connections.
- Retry with jittered backoff, but retry immediately when the browser reports a meaningful network change.
- Persist “stop reconnecting” so closing a connection banner actually stops later automatic attempts.
- After transport recovery, let each feature reconcile its own state instead of assuming every task is still active.
A practical security review
Transport encryption is only one line on the checklist. First contact should require consent. Long-term private keys should remain local. TURN access should expire quickly and be rate limited. Analytics should record outcomes and coarse timing rather than filenames, message text, connection codes, IP addresses, or full URLs.
The interface matters too. It should show whether a route is direct or relayed, keep screen-sharing state visible, provide an obvious stop action, and explain failures at the stage where they occur. “Connection error” is not enough when the actual problem is a rejected approval, exhausted relay quota, or failed integrity check.
Try the complete path
Open the uCopy connection page on both devices. Use local discovery when the devices share a public network exit, or enter a temporary code across networks. Approve first contact, then open the workspace to send a file, chat, sync the clipboard, or share a screen.
For troubleshooting, first classify the failure: device not found, handshake failed, channel connected but a feature unavailable, or transfer slow only on a relayed route. Each points to a different layer. The help page lists the information worth collecting without exposing file contents.
Reliability matters more than the P2P label
STUN helps find direct routes, TURN preserves reachability, and DataChannel carries encrypted application data. The experience users can trust comes from everything above that transport: consent, identity checks, backpressure, resume state, integrity verification, cancel propagation, and careful recovery after a refresh.
A useful P2P tool is fast when the network cooperates, resilient when it does not, quiet when trusted devices recover, and strict when a new permission is needed. That is a more demanding standard than moving one file in a demo, and it is the standard worth building for.