How to send binary data by socket with Genie?


I am developing a small web application which consists of a simple page with a form, where the user has to check some boxes but mostly choose files to upload to the server so that the server runs a process and sends back an archive containing the results.

I use Genie (nice work!), with WebChannels, and everything was fine when my files to upload were text files (Unicode) since I decoded the content on the client side in JS (with TextDecoder.decode(arraybuffer)) to send everything with Genie.WebChannels.sendMessageTo(), but it got complicated as soon as I had to send binary data (font files, zip archives…).

As I couldn’t easily find a way to send these binary data with what I could read in this channels.js file, with the Genie.WebChannels.socket.send() command, which unfortunately closes the socket, I tried to look at the conversion of my binary data into strings, to stay compatible with Genie. WebChannels.sendMessageTo(), but it’s much more complicated than expected, and it seems that JS doesn’t give exactly the same characters as Julia (the server side test works perfectly, but the data received by the JS client changes some characters so it gives a corrupted result…).

So I’m trying to go back to the JS functions of Genie to see if it’s possible to have a binary equivalent (let’s say sendDataTo()) of sendMessageTo(), compatible with channels("…/…") in which I can simply take back the (now) binary params(:payload)… I’m a beginner in JS so I’m trying to understand the logic of the channels.js file (link above).

Would some people have already looked at this more closely?



I use sockets to avoid the POST method with the submit command of the form, which resets the page as well as the socket, which bothers me to differentiate the clients…

Strangely, it seems Genie can receive some non-String data payloads:

JS: Genie.WebChannels.sendMessageTo("form", "bin", [8,8,8])
Julia: Any[8, 8, 8]
JS: Genie.WebChannels.sendMessageTo("form", "bin", new ArrayBuffer([8,8,8])
Julia: Dict{String, Any}()

Since the remark made about the possibility to send arrays of numbers, I got around the problem this way, without bothering with strings: I converted the arraybuffer into a simple array of numbers, which I simply sent…

Client (JS):

var data = new Array()
var raw_data = new Uint8Array(arraybuffer)
raw_data.forEach((value, key) => {data.push(value);});

Server (Julia):

data = params(:payload) .|> UInt8
open("", "w") do file
    write(file, data)

I don’t know if this is the cleanest way and if it solves all the problems related to binary data transfer, so the question remains open!