peers / peerjs

Simple peer-to-peer with WebRTC.
https://peerjs.com
MIT License
12.48k stars 1.43k forks source link

Massive drop in dataChannel throughput with increasing latency? #203

Closed FruitieX closed 10 years ago

FruitieX commented 10 years ago

Hi,

What is the reason that dataChannel throughput performance gets a significant drop when increasing RTT latency between the peers?

By simulating network latency and testing with a simple application that does a dc.send() on a 128 MB Uint8Array to the other peer, I'm observing the following readings:

RTT (ms) Throughput on Chromium (MB/s) Throughput on Firefox (MB/s)
0 8.24 10.09
10 2.89 7.83
20 1.52 4.26

Is there anything we can do in Peer JS to fix this, or is it an issue with the SCTP implementation in the browsers?

michelle commented 10 years ago

Hi! Could you share the specific code for the tests you're running? :).

FruitieX commented 10 years ago

Certainly! My test script makes a batch of other measurements before the throughput test, but here are the relevant parts: https://github.com/FruitieX/webrtc-benchmark/blob/master/static/rtcBenchmark.js#L213

The "server" peer just receives the data and sends back an acknowledgement message once it received everything: https://github.com/FruitieX/webrtc-benchmark/blob/master/static/rtcBenchmarkServer.js#L37

The throughput drop can also be observed with external tools such as iftop.

FruitieX commented 10 years ago

Oh, and I forgot to mention; to simulate network latency I use the tc program for Linux. Here are some helper scripts for that, but they may or may not work depending on your configuration: https://github.com/FruitieX/easy-netem

More information: http://www.linuxfoundation.org/collaborate/workgroups/networking/netem

FruitieX commented 10 years ago

I looked into this issue a bit further and tested with an own implementation just using the WebRTC API:s. The implementation rapidly called .send() on the datachannel as long as the send buffer didn't get too full (otherwise the browser would throw a error and close the datachannel). I could observe similar behavior here as with PeerJS, so I believe this is an issue with the browsers' implementations of WebRTC datachannels.

Wireshark shows a pattern where packets are sent in bursts: after a few packets have been sent by the sender, it waits to receive packets (presumably some sort of ACK packets) from the receiver before sending more data. When the latency goes up, so does the time between these spikes and data throughput is really bad as a result.

Taken with 50 ms RTT (25 up/25 down), note how the delay between the spikes is almost exactly 50 ms. Red = sender, green = receiver. Wireshark screenshot

FruitieX commented 10 years ago

The issue indeed seems to be due to the browsers' implementation of datachannels, more info: https://groups.google.com/forum/#!topic/discuss-webrtc/0synE_0zeCQ

Closing this issue as we can't really do anything about it from peerjs.