Progress bar for sending binary files in Websocket

javascript, websocket

Solution

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

Problem

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]); }; } ```

Original source