Files
grungnet/src/helpers/Peer.js
Mitchell McCaffrey 8361d6eb0b Moved to simple peer
2020-04-05 22:20:34 +10:00

98 lines
2.4 KiB
JavaScript

import SimplePeer from "simple-peer";
import BinaryPack from "js-binarypack";
import toBuffer from "blob-to-buffer";
import shortid from "shortid";
// Limit buffer size to 16kb to avoid issues with chrome packet size
// http://viblast.com/blog/2015/2/5/webrtc-data-channel-message-size/
const MAX_BUFFER_SIZE = 16000;
class Peer extends SimplePeer {
constructor(props) {
super(props);
this.currentChunks = {};
this.on("data", (packed) => {
const unpacked = BinaryPack.unpack(packed);
// If the special property __chunked is set and true
// The data is a partial chunk of the a larger file
// So wait until all chunks are collected and assembled
// before emitting the dataComplete event
if (unpacked.__chunked) {
let chunk = this.currentChunks[unpacked.id] || {
data: [],
count: 0,
total: unpacked.total,
};
chunk.data[unpacked.index] = unpacked.data;
chunk.count++;
this.currentChunks[unpacked.id] = chunk;
// All chunks have been loaded
if (chunk.count === chunk.total) {
const merged = BinaryPack.unpack(Buffer.concat(chunk.data));
this.emit("dataComplete", merged);
delete this.currentChunks[unpacked.id];
}
} else {
this.emit("dataComplete", unpacked);
}
});
}
sendPackedData(packedData) {
toBuffer(packedData, (error, buffer) => {
if (error) {
throw error;
}
super.send(buffer);
});
}
send(data) {
const packedData = BinaryPack.pack(data);
if (packedData.size > MAX_BUFFER_SIZE) {
const chunks = this.chunk(packedData);
for (let chunk of chunks) {
this.sendPackedData(BinaryPack.pack(chunk));
}
return;
} else {
this.sendPackedData(packedData);
}
}
// Converted from https://github.com/peers/peerjs/
chunk(blob) {
const chunks = [];
const size = blob.size;
const total = Math.ceil(size / MAX_BUFFER_SIZE);
const id = shortid.generate();
let index = 0;
let start = 0;
while (start < size) {
const end = Math.min(size, start + MAX_BUFFER_SIZE);
const slice = blob.slice(start, end);
const chunk = {
__chunked: true,
data: slice,
id,
index,
total,
};
chunks.push(chunk);
start = end;
index++;
}
return chunks;
}
}
export default Peer;