8

I'm using the WebRTC data channel to send JSON data. Seems to be working fine for small packets of data.

However, I'm trying to send a larger package (HTML of a webpage, base64 encoded, so maybe a few hundred KB), it never makes it to the other end.

Is there a max size?

Andy Hin
  • 30,345
  • 42
  • 99
  • 142

1 Answers1

12

I think the spec doesn't say a word about max data size. In practice 16 KB is the maximum. Take a look at this blog post and especially the throughput / packet size diagram. This result has been achieved experimentally and is the one allowing for most compatibility between webrtc implementations.

I've managed to send packets as large as 256 KB (and even larger if memory serves me right) between two Firefox instances. This was about an year ago and since then the implementation may have changed an the max data size with it.

If you want to send packets larger than 16 K you have to fragment them first. The fragmentation has to be implemented as part of you application protocol.

Svetlin Mladenov
  • 4,307
  • 24
  • 31
  • Argh. Darn! Any advice on how to implement the fragmenting? – Andy Hin Feb 13 '16 at 15:24
  • 1
    Well, the simplest way is to split a large memory buffer into chunks of 16 K (or even 8K just to be on the safe side) and send the chunk, its index and the total number of chunks as a message. On the receiving side you know the total number of chunks and you simply have to wait until you receive this number of messages from the data channel. You can even use the unordered mode of the DC if you want to get really fancy. And also I would use typed arrays instead of base64 encoding. Binary data is supported by webrtc and there is no reason IMHO to waste time and space to base64 encode. – Svetlin Mladenov Feb 13 '16 at 15:36
  • Thank you very much for your help. Going to give this a try :) – Andy Hin Feb 13 '16 at 15:43
  • So, I've chunked my data as per your suggestion and send them over using `sendData:`. However, it seems that the receiver only receives up to a certain amount before the rest never make it. The number of chunks received is related to the chunk size (smaller chunks, more chunks received) so I think it is hitting some sort of buffer max. I wanted to wait for the dataChannels `bufferedAmount` to go to zero before sending the next chunk, but this value seems to always be 0. – Andy Hin Feb 13 '16 at 21:26
  • 3
    In addition to the experimental result, you will find a similar information in the [IETF specification of WebRTC Data Channels](https://datatracker.ietf.org/doc/draft-ietf-rtcweb-data-channel/?include_text=1) in chapter 6.6, where they also recommend to limit the size of data send over data channels and bring up the threshold of 16KB: "As long as message interleaving is not supported, the sender SHOULD limit the maximum message size to 16 KB to avoid monopolization." – christianost Oct 24 '16 at 14:47
  • @AndyHin I did fragmenting with `.match(/.{1,16000}/g)` based on https://stackoverflow.com/questions/7033639/split-large-string-in-n-size-chunks-in-javascript/7033662#7033662. There will be some bytes free until 16kiB (16384 bytes) in case you want to send other data also like the chunk part number and chunk end number. – baptx Apr 24 '21 at 20:54