Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Progress bar for sending binary files in Websocket

Is there a way to track how many bytes have been sent through a Websocket connection, so I can show a progress bar.

For example I want to send an image. I already know the image size, I just need to have an event on how many bytes have been transferred in the last second for example or something similar.

Here is my code

//html
<input type="file" accept="image/*" id="input">

//js
var inputElement = document.getElementById("input");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
    var fileList = this.files;

    var connection = new WebSocket('ws://localhost:8080');
    connection.binaryType = "arraybuffer";
    connection.onopen = () => {
        connection.send(fileList[0]);
    };
}
like image 528
Doua Beri Avatar asked Mar 10 '23 05:03

Doua Beri


1 Answers

I've managed to do this with WebSocket.bufferedAmount : https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

The number of bytes of data that have been queued using calls to send() but not yet transmitted to the network. This value resets to zero once all queued data has been sent. This value does not reset to zero when the connection is closed; if you keep calling send(), this will continue to climb.

function sendBinary(binMsg, callback) {
        ws.send(binMsg);

        if (callback != null) {
            var interval = setInterval(function () {
                if (ws.bufferedAmount > 0) {
                    callback(ws.bufferedAmount)
                } else {
                    callback(0)
                    clearInterval(interval);
                }
            }, 100);
        }
    }
}

then I would call the method like this

var file = fileList[0];
sendBinary(file , function(bytesNotSent){
    if(amount==0){
       console.log('file sent');
    }else{
       var loaded = file.size - bytesNotSent;
       var percentage = Math.round((loaded * 100) / file.size );
       console.log(percentage);
    }
});

I've tested this in Chrome 58, Firefox 53 and Edge 14 and here is my conclusion on how bufferedAmount is handled:

  • Chrome 58 - constantly updates bufferedAmount when bytes are sent
  • Firefox 53 - updates bufferedAmount only when the file is sent ( in Firefox bufferedAmount has only 2 values file.size and 0
  • Edge 14 - updates bufferedAmount after 1MB of data is sent

NOTE: if you send multiple files bufferedAmount will return the amount of unsent bytes from all those files

like image 198
Doua Beri Avatar answered Mar 23 '23 12:03

Doua Beri