electron 渲染进程与主进程通信
1. 渲染进程与主进程通信的基础
Electron 的进程分为 主进程 和 渲染进程,它们通过 IPC(Inter-Process Communication,进程间通信) 进行数据交换。为了确保安全性和模块化,Electron 提供了不同的通信方式。
1.1 IPC通信方式
- 主进程负责管理窗口、文件操作、应用生命周期等。
- 渲染进程通常负责 UI 渲染,执行应用的前端逻辑。
通信的方式有两种:
- 同步通信(同步发送、接收):
- 渲染进程可以直接通过 ipcRenderer.sendSync() 向主进程发送同步消息,并等待响应。
- 主进程通过 ipcMain.handle() 响应消息。
- 异步通信(异步发送、接收):
- 渲染进程使用 ipcRenderer.send() 向主进程发送消息。
- 主进程通过 ipcMain.on() 监听并处理消息。
2. 主要API解释
2.1 ipcRenderer(渲染进程 -> 主进程)
- 用于渲染进程向主进程发送消息。
ipcRenderer.send(channel, ...args)
:发送消息到主进程。ipcRenderer.on(channel, callback)
:监听来自主进程的消息。
例子:
// 渲染进程通过 ipcRenderer.send 发送消息给主进程
ipcRenderer.send('request-data', { id: 123 });// 渲染进程通过 ipcRenderer.on 监听主进程返回的消息
ipcRenderer.on('response-data', (event, data) => {console.log('接收到主进程的响应数据:', data);
});
2.2 ipcMain(主进程 -> 渲染进程)
- 用于主进程向渲染进程发送消息。
ipcMain.on(channel, listener)
:监听来自渲染进程的消息。event.sender.send(channel, ...args)
:主进程通过 event.sender.send 向渲染进程发送消息。
例子:
// 主进程通过 ipcMain.on 监听渲染进程的消息
ipcMain.on('request-data', (event, data) => {console.log('接收到渲染进程的请求数据:', data);// 主进程通过 event.sender.send 发送响应消息event.sender.send('response-data', { status: 'success' });
});
3.preload.js 中的 API 安全暴露
为了避免直接使用 nodeIntegration
(不安全),preload.js
通过 contextBridge
安全地将主进程 API 暴露给渲染进程。
contextBridge.exposeInMainWorld()
用于暴露 API。- 渲染进程无法直接访问 Node.js 的 API,但可以通过 preload.js 暴露安全的 API。
例子:
// 在 preload.js 中暴露给渲染进程
const { contextBridge, ipcRenderer } = require('electron');contextBridge.exposeInMainWorld('electron', {// 向主进程请求通知sendNotification: (title, message) => {ipcRenderer.send('show-notification', title, message);},// 运行 Python 脚本sendRunPython: () => {ipcRenderer.send('run-python');},// 向渲染进程发送日志sendRunLog: (msg) => {ipcRenderer.send('python-log', msg);},// 主进程发来的日志回调onPythonLog: (callback) => ipcRenderer.on('python-log', (event, logMessage) => callback(logMessage))
});
渲染进程:
// 渲染进程通过 electron 访问主进程暴露的 API
window.electron.sendNotification('通知标题', '这是通知内容');
window.electron.sendRunPython();
window.electron.sendRunLog('日志内容');
4.事件(Event)和回调(Callback)机制
- 事件发送:
- 渲染进程通过
ipcRenderer.send()
向主进程发送事件。 - 主进程通过
event.sender.send()
向渲染进程发送事件。
- 渲染进程通过
- 事件监听:
- 渲染进程通过 ipcRenderer.on() 监听主进程发送的消息。
- 主进程通过 ipcMain.on() 监听渲染进程发送的消息。
4.1 on
监听器与回调机制
在渲染进程中,当需要接收主进程发送的消息时,使用 on
方法来监听:
// 渲染进程接收主进程的消息并通过回调处理
window.electron.onPythonLog((logMessage) => {console.log('接收到日志:', logMessage);
});
4.2 send
发送消息
渲染进程向主进程发送消息时,使用 send
:
// 渲染进程向主进程发送消息
window.electron.sendRunLog('渲染进程日志');
5. 通信例子
5.1 渲染进程到主进程
渲染进程发送请求执行 Python 脚本:
// 渲染进程请求运行 Python 脚本
window.electron.sendRunPython();
主进程监听并执行:
// 主进程执行 Python 脚本并返回日志
ipcMain.on('run-python', (event) => {const pythonProcess = new PythonShell('script.py');pythonProcess.stdout.on('data', (data) => {event.sender.send('python-log', `日志: ${data}`);});
});
5.2 主进程到渲染进程
主进程通过 event.sender.send()
发送日志到渲染进程:
// 主进程通过 event.sender.send 向渲染进程发送日志
ipcMain.on('run-python', (event) => {event.sender.send('python-log', 'Python 脚本运行成功');
});
渲染进程通过 onPythonLog 接收日志:
// 渲染进程接收日志
window.electron.onPythonLog((logMessage) => {console.log('日志:', logMessage);
});
6. 总结:主要通信方式
- 渲染进程 -> 主进程:通过
ipcRenderer.send()
发送消息,主进程通过ipcMain.on()
监听。 - 主进程 -> 渲染进程:通过
event.sender.send()
发送消息,渲染进程通过ipcRenderer.on()
监听。 - 通过
contextBridge
暴露安全 API:在preload.js
中暴露 API,渲染进程通过window.electron
调用主进程的功能。