You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
1.8 KiB

const MessageQueue = require("./message");
const util = require("./util");
const addEventListenerHack = util.addEventListenerHack;
const uuidv4 = util.uuidv4;
const is_uuid = util.is_uuid;
/**
*
*/
function Pipe(ws) {
this.socket = ws;
this.clients=0;
this.MAX_CLIENTS = 100;
}
const P = Pipe.prototype;
P.connect = async function(message) {
let msg;
const socket = new MessageQueue(this.socket);
try {
while ((msg = await socket.read()) !== undefined) { // Expects {com: 'open', id: uuidv4()}
try {
msg = JSON.parse(msg);
} catch(_) {continue;}
if (msg?.com === 'open' && (!message || msg?.msg === message)) {
let id = validate_id(msg?.id);
if(id) {
if(this.clients < this.MAX_CLIENTS) {
const cli = new MessageQueue(this.socket);
let open = true;
cli.premap = (raw) => {
try {
return JSON.parse(raw);
}catch(_) {return null;}
};
cli.filter = (json) => json?.id === id && (json?.com === 'msg' || ((json?.com === 'close') && cli.close() && false));
cli.map = (json) => json?.message;
cli.apply = (raw) => {
const json = {message: raw, id: id, com: 'resp'};
return JSON.stringify(json);
};
cli.on_close = (self)=> {
if(open && self.id === id) { //in case of mistaken cloning
self.send0({com: 'resp', message: 'closing', id: id});
this.clients -= 1;
open = false;
}
};
cli.id= id;
this.clients -=1;
socket.send0(JSON.stringify({com: 'resp', message: 'accepted', id: id}));
return cli;
} else {
socket.send0(JSON.stringify({com: 'resp', message: 'declined', id: id, reason: 'too many open connections'}));
}
}
}
}
} finally {
socket.close();
}
return undefined;
};
P.close = function() {
this.socket.close();
};
exports = Pipe;