Tidy up chunker code

This commit is contained in:
schlagmichdoch 2024-02-05 21:03:09 +01:00
parent 88739107e4
commit 7af51bbd5f

View file

@ -673,28 +673,28 @@ class Peer {
this._chunker._onReceiveConfirmation(bytesReceived); this._chunker._onReceiveConfirmation(bytesReceived);
} }
async _onFileReceived(fileBlob) { async _onFileReceived(file) {
const acceptedHeader = this._acceptedRequest.header.shift(); const acceptedHeader = this._acceptedRequest.header.shift();
this._totalBytesReceived += fileBlob.size; this._totalBytesReceived += file.size;
let duration = (Date.now() - this._timeStart) / 1000; let duration = (Date.now() - this._timeStart) / 1000;
let size = Math.round(10 * fileBlob.size / 1000000) / 10; let size = Math.round(10 * file.size / 1000000) / 10;
let speed = Math.round(100 * fileBlob.size / 1000000 / duration) / 100; let speed = Math.round(100 * file.size / 1000000 / duration) / 100;
Logger.log(`File received.\n\nSize: ${size} MB\tDuration: ${duration} s\tSpeed: ${speed} MB/s`); Logger.log(`File received.\n\nSize: ${size} MB\tDuration: ${duration} s\tSpeed: ${speed} MB/s`);
this._sendMessage({type: 'file-transfer-complete', success: true, size: size, duration: duration, speed: speed}); this._sendMessage({type: 'file-transfer-complete', success: true, size: size, duration: duration, speed: speed});
const sameSize = fileBlob.size === acceptedHeader.size; const sameSize = file.size === acceptedHeader.size;
const sameName = fileBlob.name === acceptedHeader.name const sameName = file.name === acceptedHeader.name
if (!sameSize || !sameName) { if (!sameSize || !sameName) {
this._abortTransfer(); this._abortTransfer();
} }
// include for compatibility with 'Snapdrop & PairDrop for Android' app // include for compatibility with 'Snapdrop & PairDrop for Android' app
Events.fire('file-received', fileBlob); Events.fire('file-received', file);
this._filesReceived.push(fileBlob); this._filesReceived.push(file);
if (this._acceptedRequest.header.length) return; if (this._acceptedRequest.header.length) return;
@ -1276,7 +1276,6 @@ class WSPeer extends Peer {
if (message.type === 'chunk') { if (message.type === 'chunk') {
const data = base64ToArrayBuffer(message.chunk); const data = base64ToArrayBuffer(message.chunk);
this._onData(data); this._onData(data);
} }
else { else {
this._onMessage(message); this._onMessage(message);
@ -1577,14 +1576,28 @@ class FileChunker {
} }
_readChunk() { _readChunk() {
if (this._currentlySending || this._isFileEnd()) return; if (this._currentlySending || !this._bufferHasSpaceForChunk() || this._isFileEnd()) return;
this._currentlySending = true; this._currentlySending = true;
const chunk = this._file.slice(this._bytesSent, this._bytesSent + this._chunkSize); const chunk = this._file.slice(this._bytesSent, this._bytesSent + this._chunkSize);
this._reader.readAsArrayBuffer(chunk); this._reader.readAsArrayBuffer(chunk);
} }
_onChunkRead(chunk) {} _onChunkRead(chunk) {
if (!chunk.byteLength) return;
this._currentlySending = false;
this._onChunk(chunk);
this._bytesSent += chunk.byteLength;
// Pause sending when reaching the high watermark or file end
if (!this._bufferHasSpaceForChunk() || this._isFileEnd()) return;
this._readChunk();
}
_bufferHasSpaceForChunk() {}
_onReceiveConfirmation(bytesReceived) {} _onReceiveConfirmation(bytesReceived) {}
@ -1610,26 +1623,16 @@ class FileChunkerRTC extends FileChunker {
this._peerConnection = peerConnection; this._peerConnection = peerConnection;
this._dataChannel = dataChannel; this._dataChannel = dataChannel;
this._highWatermark = 4194304; // 4 MB this._highWatermark = 10485760; // 10 MB
this._lowWatermark = 1048576; // 1 MB this._lowWatermark = 4194304; // 4 MB
// Set buffer threshold // Set buffer threshold
this._dataChannel.bufferedAmountLowThreshold = this._lowWatermark; this._dataChannel.bufferedAmountLowThreshold = this._lowWatermark;
this._dataChannel.addEventListener('bufferedamountlow', _ => this._readChunk()); this._dataChannel.addEventListener('bufferedamountlow', _ => this._readChunk());
} }
_onChunkRead(chunk) { _bufferHasSpaceForChunk() {
if (!chunk.byteLength) return; return this._dataChannel.bufferedAmount + this._chunkSize < this._highWatermark;
this._currentlySending = false;
this._onChunk(chunk);
this._bytesSent += chunk.byteLength;
// Pause sending when reaching the high watermark or file end
if (this._dataChannel.bufferedAmount > this._highWatermark || this._isFileEnd()) return;
this._readChunk();
} }
_onReceiveConfirmation(bytesReceived) { _onReceiveConfirmation(bytesReceived) {
@ -1643,17 +1646,12 @@ class FileChunkerWS extends FileChunker {
super(file, onChunkCallback); super(file, onChunkCallback);
} }
_onChunkRead(chunk) { _bytesCurrentlySent() {
this._currentlySending = false; return this._bytesSent - this._bytesReceived;
}
this._onChunk(chunk); _bufferHasSpaceForChunk() {
this._bytesSent += chunk.byteLength; return this._bytesCurrentlySent() + this._chunkSize <= this._maxBytesSentWithoutConfirmation;
// if too many bytes sent without confirmation by receiver or if end of file -> abort
const bytesCurrentlySent = this._bytesSent - this._bytesReceived;
if (bytesCurrentlySent > this._maxBytesSentWithoutConfirmation - this._chunkSize || this._isFileEnd()) return;
this._readChunk();
} }
_onReceiveConfirmation(bytesReceived) { _onReceiveConfirmation(bytesReceived) {
@ -1695,12 +1693,13 @@ class FileDigester {
if (this._bytesReceived < this._size) return; if (this._bytesReceived < this._size) return;
// we are done // we are done
const blob = new Blob(this._buffer) const file = new File(this._buffer, this._name, {
this._buffer = null;
this._onFileCompleteCallback(new File([blob], this._name, {
type: this._mime, type: this._mime,
lastModified: new Date().getTime() lastModified: new Date().getTime()
})); })
this._buffer = [];
this._onFileCompleteCallback(file);
} }
} }