At first, I hope you understand that I'm not good at english.
For file transfer, in Mesh topology, in Chrome,
When buffered amount is 16MB, the channel is closed with an error message.
"Uncaught NetworkError: Failed to execute 'send' on 'RTCDataChannel': Could not send data"
(It is in chrome, not firefox.)
How to send a file(more than 16MB)?
var chunkSize = 16384;
onmessage = function(event) {
var file = event.data[0],
callbackId = event.data[1],
totalSize = file.size,
chunks = [],
curSize = 0,
reader,
chunk;
if (!FileReaderSync) {
reader = new FileReader();
reader.onload = function(event) {
console.log('chunking...');
chunks.push(event.target.result);
curSize += chunkSize;
slice();
};
slice();
} else {
reader = new FileReaderSync();
while (curSize < totalSize) {
console.log('chunking...');
chunk = file.slice(curSize, curSize + chunkSize);
chunks.push(reader.readAsArrayBuffer(chunk));
curSize += chunkSize;
}
postMessage([chunks, file.name, callbackId]);
}
function slice() {
if (curSize > totalSize) {
postMessage([chunks, file.name, callbackId]);
} else {
chunk = file.slice(curSize, curSize + chunkSize);
reader.readAsArrayBuffer(chunk);
}
}
};
_fileToPeers: function(chunks, fileName, progressCallbackId) {
var callback = callbacks[progressCallbackId],
chunkCount,
peerCount = 0;
objForEach(this.peers, function(peer) {
var channel = peer.fileChannel;
peerCount += 1;
if (channel) {
chunkCount = 0;
chunks.forEach(function(chunk) {
channel.send(chunk);
chunkCount += 1;
console.log('sending...'); // abnormal works!
callback(peerCount, chunkCount); // abnormal works!
});
channel.send(['end', fileName].join(','));
}
});
delete callbacks[progressCallbackId];
},
I tried to solve this problem.
I just use the recursive function call with setTimeout.
_fileToPeers: function(chunks, fileName, progressCallbackId) {
var callback = callbacks[progressCallbackId];
objForEach(this.peers, function(peer) {
var channel = peer.fileChannel;
if (channel && !channel.using) {
channel.using = true;
this._chunksInChannel(chunks, 0, fileName, channel, callback);
}
}, this);
delete callbacks[progressCallbackId];
},
_chunksInChannel: function(chunks, chunkIdx, fileName, channel, callback) {
var length = chunks.length,
doNext = chunkIdx < length;
while (doNext) {
if (channel.bufferedAmount > CHANNEL_BUFFER_MAX) {
setTimeout(function () {
this._chunksInChannel(chunks, chunkIdx, fileName, channel, callback);
}.bind(this), 500);
doNext = false;
} else {
channel.send(chunks[chunkIdx]);
chunkIdx += 1;
if (chunkIdx === length) {
channel.send(['end', fileName].join(','));
doNext = false;
channel.using = false;
}
callback(chunkIdx);
}
}
},
Haven't you something better?