Support message separation for multiple inputs from same user. (#142)

This commit is contained in:
Savinda Senevirathne
2020-11-06 10:55:40 +05:30
committed by GitHub
parent 202a6a2715
commit 51173e37f2
11 changed files with 241 additions and 114 deletions

View File

@@ -66,14 +66,15 @@ async function main() {
console.log("Ready to accept inputs.");
const input_pump = () => {
rl.question('', async (inp) => {
rl.question('', (inp) => {
if (inp.startsWith("read "))
hpc.sendContractReadRequest(inp.substr(5))
else {
const submissionStatus = await hpc.sendContractInput(inp);
if (submissionStatus && submissionStatus != "ok")
console.log("Input submission failed. reason: " + submissionStatus);
hpc.sendContractInput(inp).then(submissionStatus => {
if (submissionStatus && submissionStatus != "ok")
console.log("Input submission failed. reason: " + submissionStatus);
});
}
input_pump();

View File

@@ -18,10 +18,13 @@ hpc.events.on("user_message", (pubKey, message) => {
}
else {
user.sendOutput("Echoing: " + userInput);
user.closeChannel();
}
});
hpc.events.on("user_finished", (pubKey) => {
hpc.users[pubKey].closeChannel();
});
const npl = hpc.npl;
// Npl channel always connected if contract is not in readonly mode.

View File

@@ -31,26 +31,46 @@ function HotPocketChannel(fd, userPubKey, events) {
let socket = null;
if (fd > 0) {
socket = fs.createReadStream(null, { fd: fd });
const dataParts = [];
let dataParts = [];
let msgCount = -1;
let msgLen = -1;
let bytesRead = 0;
let pos = 0;
socket.on("data", (buf) => {
if (msgLen == -1) {
// First two bytes indicate the message len.
const msgLenBuf = readBytes(buf, 0, 4);
if (msgLenBuf) {
msgLen = msgLenBuf.readUInt32BE();
const msgBuf = readBytes(buf, 4, buf.byteLength - 4);
dataParts.push(msgBuf)
bytesRead = msgBuf.byteLength;
}
} else {
dataParts.push(buf);
bytesRead += buf.length;
pos = 0;
if (msgCount == -1) {
const msgCountBuf = readBytes(buf, 0, 4)
msgCount = msgCountBuf.readUInt32BE();
pos += 4;
}
if (bytesRead == msgLen) {
msgLen == -1;
events.emit("user_message", userPubKey, Buffer.concat(dataParts));
while (pos < buf.byteLength) {
if (msgLen == -1) {
const msgLenBuf = readBytes(buf, pos, 4);
pos += 4;
msgLen = msgLenBuf.readUInt32BE();
}
let possible_read_len;
if (((buf.byteLength - pos) - msgLen) >= 0) {
// Can finish reading a full message.
possible_read_len = msgLen;
msgLen = -1;
} else {
// Only partial message is recieved.
possible_read_len = buf.byteLength - pos
msgLen -= possible_read_len;
}
const msgBuf = readBytes(buf, pos, possible_read_len);
pos += possible_read_len;
dataParts.push(msgBuf)
if (msgLen == -1) {
events.emit("user_message", userPubKey, Buffer.concat(dataParts));
dataParts = [];
msgCount--
}
if (msgCount == 0) {
msgCount = -1
events.emit("user_finished", userPubKey);
}
}
});
@@ -67,7 +87,12 @@ function HotPocketChannel(fd, userPubKey, events) {
}
this.sendOutput = function (output) {
fs.writeSync(fd, output);
const outputStringBuf = Buffer.from(output);
let headerBuf = Buffer.alloc(4);
// Writing message length in big endian format.
headerBuf.writeUInt32BE(outputStringBuf.byteLength)
fs.writeSync(fd, headerBuf);
fs.writeSync(fd, outputStringBuf);
}
this.closeChannel = function () {