JavaScript - Send ArrayBuffer data to backend over websocket [guacamole]

513 Views Asked by At

I need to send data (a file) via websocket to my guacamole backend using the guacamole-common-js library.

The scenario is the following:

  1. Drag and drop area is created
  2. User puts a file in this area
  3. File is read
  4. A guac filestream is created and the file is sent to the guac backend

Steps 1 to 3 are already working, but I do not know, how to send the file to the guacamole backend.

That's my function when a file is dropped: (guac is a global var that initialized the Guacamole-Client function)

 function drop(ev){
    ev.preventDefault();
    if (ev.dataTransfer.items) {
        for (var i = 0; i < ev.dataTransfer.items.length; i++) {
        if (ev.dataTransfer.items[i].kind === 'file') {
            var file = ev.dataTransfer.items[i].getAsFile();
            var reader = new FileReader();
            reader.onloadend = function fileContentsLoaded (e){
                const stream = guac.createFileStream(file.type, file.name);
                const bytes  = new Uint8Array(reader.result);
                stream.sendBlob(bytes.buffer)
                stream.sendEnd()
            };
            console.log(file)
            reader.readAsArrayBuffer(file);
        }
        }
    } else {
        for (var i = 0; i < ev.dataTransfer.files.length; i++) {
        console.log(ev.dataTransfer.files[i].name);
        }
    }
}

The backend is also receiving the data and I am able to open the file on the remote server to which the file is sent by guacd, but the file does only contain kind of binary data.

Does someone already managed this or has an idea how I could send the data?

2

There are 2 best solutions below

0
On BEST ANSWER

I already found a solution...

The guacamole-common-js lib already provides a function for sending the buffer to the backend...

My "drop" functions looks now the following:

function drop(ev){
    ev.preventDefault();
    if (ev.dataTransfer.items) {
        for (var i = 0; i < ev.dataTransfer.items.length; i++) {
        if (ev.dataTransfer.items[i].kind === 'file') {
            var file = ev.dataTransfer.items[i].getAsFile();
            var reader = new FileReader();
            reader.onloadend = function fileContentsLoaded (e){
                const stream = guac.createFileStream(file.type, file.name);
                var bufferWriter = new Guacamole.ArrayBufferWriter(stream)
                bufferWriter.sendData(reader.result)
                bufferWriter.sendEnd()
            };
            reader.readAsArrayBuffer(file);
        }
    }
    } else {
        for (var i = 0; i < ev.dataTransfer.files.length; i++) {
        console.log(ev.dataTransfer.files[i].name);
        }
    }
}
1
On

If you use Node.js in Backend, try handle it with Buffer.toString or Buffer.from.