进程通信 在 Electron 中,主进程和渲染进程之间可以通过 IPC(Inter-Process Communication,进程间通信) 来传递数据。Electron 提供了 ipcMain 和 ipcRenderer 模块来实现这种通信。
1.主进程到渲染进程的通信 主进程通过 webContents.send 方法向渲染进程发送消息:
const { app, BrowserWindow } = require(‘electron’); let mainWindow = null; app.whenReady().then(() => { mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
}); mainWindow.loadFile(‘index.html’); // 主进程向渲染进程发送数据 mainWindow.webContents.send(‘main-to-renderer’, { message: ‘Hello from Main Process!’ }); });
渲染进程通过 ipcRenderer.on 或 ipcRenderer.once 方法监听主进程发送的消息:
const { ipcRenderer } = require(‘electron’); // 监听主进程发送的消息 ipcRenderer.on(‘main-to-renderer’, (event, data) => { console.log(‘Received data from Main Process:’, data); });
2.渲染进程到主进程的通信 渲染进程可以通过 ipcRenderer.send 方法向主进程发送消息:
const { ipcRenderer } = require(‘electron’); // 向主进程发送数据 ipcRenderer.send(‘renderer-to-main’, { message: ‘Hello from Renderer Process!’ });
主进程通过 ipcMain.on 或 ipcMain.once 方法监听渲染进程发送的消息:
const { app, BrowserWindow, ipcMain } = require(‘electron’); let mainWindow = null; app.whenReady().then(() => { mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
}); mainWindow.loadFile(‘index.html’); // 监听渲染进程发送的消息 ipcMain.on(‘renderer-to-main’, (event, data) => {
console.log('Received data from Renderer Process:', data);
}); });
3.同步通信(请求-响应模式) 主进程通过 ipcMain.handle 方法处理渲染进程的请求:
const { app, BrowserWindow, ipcMain } = require(‘electron’); let mainWindow = null; app.whenReady().then(() => { mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
}); mainWindow.loadFile(‘index.html’); // 处理渲染进程的请求 ipcMain.handle(‘get-data’, async (event, data) => {
console.log('Received request from Renderer Process:', data);
return { message: 'Response from Main Process' };
}); });
渲染进程通过 ipcRenderer.invoke 方法发送请求并等待响应:
const { ipcRenderer } = require(‘electron’); // 发送请求并等待响应 ipcRenderer.invoke(‘get-data’, { message: ‘Request from Renderer Process’ }) .then((response) => {
console.log('Received response from Main Process:', response);
});
4.preload.js 从 Electron 5 开始,contextIsolation 默认为 true,这意味着渲染进程无法直接访问 Node.js 模块。为了在安全的环境下传递数据,可以使用 preload.js:
const { app, BrowserWindow } = require(‘electron’); let mainWindow = null; app.whenReady().then(() => { mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'), // 指定 preload.js 文件
contextIsolation: true
}
}); mainWindow.loadFile(‘index.html’); });
preload.js 是一个特殊的脚本,运行在渲染进程中,但可以访问主进程的 API:
const { contextBridge, ipcRenderer } = require(‘electron’); contextBridge.exposeInMainWorld(‘electronAPI’, { sendMessage: (message) => ipcRenderer.send(‘renderer-to-main’, message), receiveMessage: (callback) => ipcRenderer.on(‘main-to-renderer’, callback), invoke: (channel, data) => ipcRenderer.invoke(channel, data) });
渲染进程通过 preload.js 暴露的 API 访问主进程 :
// 使用 preload.js 暴露的 API window.electronAPI.sendMessage({ message: ‘Hello from Renderer Process!’ }); window.electronAPI.receiveMessage((event, data) => { console.log(‘Received data from Main Process:’, data); }); window.electronAPI.invoke(‘get-data’, { message: ‘Request from Renderer Process’ }) .then((response) => {
console.log('Received response from Main Process:', response);
});