truss/comm/socket.ipc.js
2018-12-23 07:56:44 -06:00

182 lines
2.9 KiB
JavaScript

const {EventEmitter} = require('events');
let clientId = 0;
class IpcClient extends EventEmitter {
constructor(service) {
super();
this.id = clientId;
process.send({
type: 'connect',
payload: {
clientId: this.id,
service,
},
});
const messageListener = ({type, payload}) => {
switch (type) {
case 'connection_to':
if (payload.clientId !== this.id) { return; }
this.connection = payload.connection;
this.to = payload.to;
setTimeout(() => {
this.emit('ready');
}, 0);
break;
case 'connection_error':
if (payload.clientId !== this.id) { return; }
process.off('message', messageListener);
setTimeout(() => {
this.emit('error', {code: 'ENOTFOUND'});
}, 0);
break;
case 'client_recv':
if (payload.clientId !== this.id) { return; }
process.off('message', messageListener);
setTimeout(() => {
this.emit('data', payload.data);
this.emit('end');
}, 0);
break;
}
};
process.on('message', messageListener);
clientId++;
}
end() {}
setEncoding() {}
write(data) {
process.send({
type: 'client_send',
payload: {
clientId: this.id,
data,
to: this.to,
},
});
}
}
exports.client = function(address) {
return new IpcClient(address);
}
class IpcSocket extends EventEmitter {
constructor(clientId, to) {
super();
return {
emit: this.emit,
end() {
this.emit('end');
},
on: this.on,
setEncoding() {},
write(data) {
process.send({
type: 'server_send',
payload: {
clientId,
data,
to,
},
});
},
};
}
}
class IpcServer extends EventEmitter {
constructor() {
super();
const connections = {};
return {
emit: this.emit,
listen() {
process.send({
type: 'listening',
});
setTimeout(() => {
this.emit('listening');
}, 0);
process.on('message', ({type, payload}) => {
switch (type) {
case 'connection_from':
const socket = new IpcSocket(payload.clientId, payload.from);
connections[payload.clientId] = socket;
this.emit('connection', socket);
socket.on('end', () => {
delete connections[payload.clientId];
});
break;
case 'server_recv':
if (connections[payload.clientId]) {
connections[payload.clientId].emit('data', payload.data);
}
break;
}
});
},
on: this.on,
setEncoding() {},
};
}
}
exports.server = function() {
return new IpcServer();
}