electron 主进程调用渲染进程发送请求
Opened this issue · 1 comments
Topppy commented
背景
- 两个进程的cookie不共享,因此需要在渲染进程发送
- 主进程通知渲染进程发送,并等待请求响应结果,再做下一步处理。
实现
由于IPC都是EventEmmiter模式的,因此我们需要用Promise包装一下 IPC的通知。
主进程发送消息给渲染进程
单向通知,不关心接收方的响应
/**
* 主进程向渲染进程发送消息
* @param channel 频道
* @param msg 消息数据
*/
const sendToRenderer = (channel: string, msg: any) => {
// 封装webcontent的send方法
}
主进程发送消息给渲染进程,并等待渲染进程的响应
双向通信,等待响应数据好继续执行任务
/**
* 主进程向渲染进程发送消息,并等待渲染进程的响应
* @param channel 频道
* @param msg 消息
* @return Pomise<any>
*/
export const callRenderer = (channel: string, msg: any) => new Promise((resolve, reject) => {
const onData = (e: any, result: any) => {
resolve(result)
}
const { sendChannel, dataChannel } = getIPCChannels(channel)
// 监听渲染进程的响应
ipcMain.once(dataChannel, onData)
const mainWindow = BrowserWindow.getFocusedWindow()
if (mainWindow && mainWindow.webContents) {
// 发送消息
mainWindow.webContents.send(sendChannel, msg)
} else {
// 取消监听
ipcMain.removeListener(dataChannel, onData)
}
})
渲染进程响应主进程调用
与 callRenderer 配合使用
/**
* 响应Main进程调用并返回数据
* @param channel 频道
* @param callback 回调, (data:any) => Promise<any>
*/
export const answerMain = (
channel: string,
callback: (data: any) => Promise<any>
) => {
const { sendChannel, dataChannel } = getIPCChannels(channel)
const listener = async (event: any, data: any) => {
try {
log.info('answerMain params:', data)
const res = await callback(data)
log.info('answerMain data', res)
ipcRenderer.send(dataChannel, res)
} catch (error) {
log.info('answerMain error:')
log.error(error)
ipcRenderer.send(dataChannel, null)
}
}
ipcRenderer.on(sendChannel, listener)
}
使用 case: 主进程调用渲染进程发送请求
// main
const data: any = await callRenderer('api-report', deviceInfo)
// render
answerMain('api-report', aync () => {
await doSomething()
return data
})