This repository has been archived by the owner on Feb 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathRpc.js
55 lines (52 loc) · 1.62 KB
/
Rpc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
const { ipcRenderer } = require('electron')
// https://www.jsonrpc.org/specification
// use on renderer
class Rpc {
constructor() {
this.id = 1
}
async send(method, args) {
let _id = this.id++
ipcRenderer.send('rpc', {"jsonrpc": "2.0", "method": method, "params": args, "id": _id})
return new Promise((resolve, reject) => {
let timeoutHandler = undefined
let responseHandler = (ev, response) => {
if(timeoutHandler){
clearInterval(timeoutHandler)
}
// response belongs to corresponding request above: ipcRenderer.send
if(response.id === _id){
ipcRenderer.removeListener('rpc', responseHandler)
if(response.error){
reject(response.error)
} else if('result' in response){
resolve(response.result)
} else {
// malformed
}
}
}
ipcRenderer.on('rpc', responseHandler)
// auto-unsubscribe after timeout to avoid memory leak
timeoutHandler = setTimeout(()=>{
ipcRenderer.removeListener('rpc', responseHandler)
reject(new Error('rpc timed out'))
}, 10*1000)
})
}
}
// use on main
const setupRpc = (namespace, obj) => {
ipcMain.on('rpc', async (ev, data) => {
let parts = data.method.split('.')
if(parts[0] !== namespace) return
const method = parts[1]
if(typeof obj[method] === 'function') {
let result = await obj[method](data.params)
let response = {"jsonrpc": "2.0", "result": result, "id": data.id}
ev.sender.send('rpc', response)
}
})
}
module.exports.Rpc = Rpc
module.exports.setupRpc = setupRpc