I'm trying to simply upload a file to a node.js server.
To do this, I'm using the file API and readAsArrayBuffer. Here's the code that's called when the input file "change" event is fired, along with some hepler functions (and I'm using the COBY library for socket sending and other event setup, the binaryType is set to arraybuffer):
COBY.events = {
"file": (e) => {
files = Array.from(e.target.files);
startReadingFile(files[0]);
}
};
function startReadingFile(file) {
readFileFrom(file, 0, chunkSize, (array, r) => {
COBY.socketSend({"start uploading a file": {
name:file.name,
type:file.type,
size:file.size,
data:(array)
}});
console.log("didnt something?", r, Array.from(r));
});
}
function readFileFrom(file, start, end, callback) {
var sliced = file.slice(start, end);
var reader = new FileReader();
reader.onload = (event) => {
result = (event.target.result);
var arr = Array.from(new Uint8Array(result));
if(callback && callback.constructor == Function) {
currentPosition = end;
callback(arr, result);
}
}
reader.readAsArrayBuffer(sliced);
}
And on my server (I'm using the coby-node library which is the node.js version of the COBY client library):
var coby = require("coby-node");
var fs = require("fs");
var files = {};
var kilobyte = 1024;
function makeBigFile(name, number) {
var test = fs.createWriteStream("./" + name, {flags: "w+"});
console.log("OK?",name);
[...Array(number)].forEach((x, i) => test.write(i+"\n"));
}
//makeBigFile("OKthere.txt", 12356);
coby.startAdanServer({
onOpen:(cs) => {
console.log("something just connected! Let's send it something");
// cs.send({"Whoa man !":1234});
cs.send({asdf :3456789});
},
onAdanMessage: (cs, msg) => {
// console.log("HMM weird just got this message...", msg);
},
adanFunctions: {
"do something important": (cs, data) => {
console.log("I just got some message:", data);
console.log(cs.server.broadcast);
cs.server.broadcast({"look out":"here I am"}, {
current: cs
});
cs.send({message:"OK I did it I think"});
},
"start uploading a file": (cs, data) => {
if(data.data && data.data.constructor == Array) {
var name = data["name"]
files[name] = {
totalSize:data.size,
downloadedSize:0
};
files[name]["handler"] = fs.createWriteStream("./" + data.name, {
flags: "w+"
});
files[name]["handler"].on("error", (err) => {
console.log("OY vay", err);
});
cs.send({"ok dude I need more": {
name:name,
bytePositionToWriteTo:0,
totalLength:files[name]["totalSize"]
}});
}
},
"continue uploading file": (cs, data) => {
var name = data.name;
if(files[name]) {
var handler = files[name]["handler"];
var uint = Uint8Array.from(data.bufferArray);
var myBuffer = Buffer.from(uint.buffer);
var start = data.startPosition || 0,
end = myBuffer.byteLength + start;
files[name].downloadedSize += myBuffer.byteLength;
if(files[name].downloadedSize < files[name]["totalSize"]) {
cs.send({"ok dude I need more": {
name:name,
bytePositionToWriteTo:files[name].downloadedSize,
totalLength:files[name]["totalSize"]
}});
try {
handler.write(myBuffer);
} catch(e) {
console.log("writing error: ", e);
}
} else {
end = files[name]["totalSize"];
handler.write(myBuffer);
console.log("finished, I think?");
console.log(files[name].downloadedSize, "total: ", files[name]["totalSize"]);
console.log(" start: ", start, "end: ", end);
}
}
}
},
intervalLength:1000
});
function startUnity() {
coby.cmd(`./MyUnity/Editor/Unity.exe -batchmode -quit -projectPath "./MyUnity/totally empty" -executeMethod COBY.Start -logfile ./new123folder/wow.txt`, {
onData:(data) => {
console.log(data);
},
onError:(data) => {
console.log(data);
},
onExit:(exitCode) => {
console.log("exitted with code: " + exitCode);
},
onFail:(msg) => {
console.log(msg);
}
});
}
So far this actualy uploads a file, you can test it with npm install coby-node
, but its taking a lot more time because I'm JSON.stringifing an Array.from(new Uint8Array(/* the ArrayBuffer result */))
and then on the server side I'm re-JSON parsing it, but how do I just send the actual ArrayBuffer to the websocket? I want to send the arraybuffer along with the name of the file and other data, so I want to include it in a JSON object, but when I JSON.stringify(/an ArrayBuffer/) the result is always [], and IDK how to send an ArrayBuffer with my own data ???
Also it seems to be taking a lot of time with Array.from(new Uint8Array(arrayBufer)) do you think readAsDataURL would be faster?
I AM able to, btw, send an arraybuffer by ITSELF via websocket with binayType="arraybuffer", but how do I include the filename with it??