ipc.js
1 const fs = require('./fs.js'); 2 const ipc = require('node-ipc'); 3 const {parse, stringify} = require('flatted/cjs'); 4 5 class IPC { 6 7 constructor(options) { 8 this.logger = options.logger; 9 this.socketPath = options.socketPath || fs.dappPath(".embark/embark.ipc"); 10 this.ipcRole = options.ipcRole; 11 ipc.config.silent = true; 12 this.connected = false; 13 } 14 15 connect(done) { 16 const self = this; 17 function connecting(_socket) { 18 let connectedBefore = false, alreadyDisconnected = false; 19 ipc.of['embark'].on('connect',function() { 20 connectedBefore = true; 21 if (!alreadyDisconnected) { 22 self.connected = true; 23 done(); 24 } 25 }); 26 ipc.of['embark'].on('disconnect',function() { 27 self.connected = false; 28 ipc.disconnect('embark'); 29 30 // we only want to trigger the error callback the first time 31 if (!connectedBefore && !alreadyDisconnected) { 32 alreadyDisconnected = true; 33 done(new Error("no connection found")); 34 } 35 }); 36 } 37 38 ipc.connectTo('embark', this.socketPath, connecting); 39 } 40 41 serve() { 42 fs.mkdirpSync(fs.dappPath(".embark")); 43 ipc.serve(this.socketPath, () => {}); 44 ipc.server.start(); 45 46 this.logger.info(`pid ${process.pid} listening on ${this.socketPath}`); 47 } 48 49 on(action, done) { 50 const self = this; 51 ipc.server.on('message', function(messageString, socket) { 52 const message = parse(messageString); 53 if (message.action !== action) { 54 return; 55 } 56 let reply = function(error, replyData) { 57 self.reply(socket, action, error, replyData); 58 }; 59 done(message.data, reply, socket); 60 }); 61 } 62 63 reply(client, action, error, data) { 64 const message = stringify({action, data, error: (error && error.stack)}); 65 ipc.server.emit(client, 'message', message); 66 } 67 68 listenTo(action, callback) { 69 ipc.of['embark'].on(action, (messageString) => { 70 callback(parse(messageString)); 71 }); 72 } 73 74 broadcast(action, data) { 75 ipc.server.broadcast(action, stringify(data)); 76 } 77 78 once(action, cb) { 79 ipc.of['embark'].once('message', function(messageString) { 80 const message = parse(messageString); 81 if (message.action !== action) { 82 return; 83 } 84 cb(message.error, message.data); 85 }); 86 } 87 88 request(action, data, cb) { 89 if (cb) { 90 this.once(action, cb); 91 } 92 ipc.of['embark'].emit('message', stringify({action: action, data: data})); 93 } 94 95 isClient() { 96 return this.ipcRole === 'client'; 97 } 98 99 isServer() { 100 return this.ipcRole === 'server'; 101 } 102 103 } 104 105 module.exports = IPC;