进程间通信
前言
通信主要是主进程和渲染进程间的通信。由于安全性,渲染进程不能直接调用主进程的API,所以需要通过preload模块搭一个桥梁进行通信。
渲染器进程到主进程(单向)
在Preload中使用ipcRenderer.send API发送消息,在主进程中使用ipcMain.on接收。
javascript
// proload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electronApi', {
setTitle: (title) => ipcRenderer.send('set-title', title)
});
// renderer.js
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
const title = titleInput.value
window.electronAPI.setTitle(title)
});
// main.js
ipcMain.on('set-title', (event, title) => {
const webContents = event.sender;
const win = BrowserWindow.fromWebContents(webContents);
win.setTitle(title)
})
渲染器进程到主进程(双向)
主要场景是渲染进程调用主进程模块并等待结果。这可以通过将ipcRenderer.invoke与ipcMain.handle搭配使用来完成。
javascript
// proload.js
// 这里返回一个Promise,且内容是handle回调返回的内容
const ret = ipcRenderer.invoke('openDialog')
ret.then((result) => {
console.log(result) // test 111
})
// main.js
ipcMain.handle('openDialog', () => {
return 'test 111'
})
主进程到渲染进程
由于渲染器可能存在在多个,所以需要知道将消息发送到哪个渲染器。消息主要是通过WebContents
实例的send
方法,使用方法和ipcRenderer.send
相同。
javascript
// proload.js
// 这里返回一个Promise,且内容是handle回调返回的内容
ipcRenderer.on('updateValue', (event, value) => {
console.log(value) // 111
event.sender.send('returnUpdate', value + ': is updated')
})
// main.js
// mainWindow是窗口实例引用
mainWindow.webContents.send('updateValue', 111)
ipcMain.on('returnUpdate', (event, value) => {
console.log(value) // 111: is updated
})
渲染器到渲染器
没有直接方法通信,只能通过间接通信。
- 通过主进程作代码通信。
- 从主进程将一个MessagePort传递到两个渲染器。