1. IPC 通道
在 Electron 中,ipcMain 和 ipcRenderer 模块允许主进程和渲染进程通过自定义的通道进行消息传递。这些通道是开发者自定义命名的,可以实现双向通信。
主进程(main.js):
const { app, BrowserWindow, ipcMain } = require('electron');
function createWindow() {
let win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
});
win.loadFile('index.html');
}
app.whenReady().then(createWindow);
// 监听来自渲染进程的消息
ipcMain.on('channel-name', (event, arg) => {
console.log(arg); // 输出传递的消息内容
});
预加载脚本(preload.js):
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('api', {
sendMessage: (msg) => ipcRenderer.send('channel-name', msg)
});
渲染进程(renderer.js):
document.getElementById('sendButton').addEventListener('click', () => {
window.api.sendMessage('Hello from Renderer');
});
2. 理解上下文隔离的进程
在 Electron 中,使用预加载脚本和 contextBridge API 可以安全地在上下文隔离的渲染进程中暴露 Node.js 和 Electron 功能。
预加载脚本(preload.js) 的示例代码如上所示。
3. 模式 1:渲染进程到主进程(单向)
在这种模式下,渲染进程可以发送消息到主进程,但不直接接收回复。
渲染进程(renderer.js):
ipcRenderer.send('channel-for-main', 'This is a one-way message to main');
主进程(main.js):
ipcMain.on('channel-for-main', (event, message) => {
console.log(message);
});
4. 模式 2:渲染进程到主进程(双向)
使用 invoke 和 handle 实现渲染进程和主进程之间的双向通信。
渲染进程(renderer.js):
async function fetchData() {
try {
const result = await ipcRenderer.invoke('query-data', 'requestData');
console.log(result);
} catch (e) {
console.error(e);
}
}
fetchData();
主进程(main.js):
ipcMain.handle('query-data', async (event, arg) => {
return `Received request: ${arg}`;
});
5. 模式 3:主进程到渲染进程
向特定的渲染进程发送消息。
主进程(main.js):
let win = new BrowserWindow({/* options */});
win.webContents.send('message-for-renderer', 'Hello, renderer!');
6. 模式 4:渲染进程到渲染进程
通过主进程作为中间者或使用 MessagePort。
主进程(main.js):
ipcMain.on('send-to-other-renderer', (event, message) => {
let windows = BrowserWindow.getAllWindows();
windows.forEach(win => {
if (win.webContents !== event.sender) {
win.webContents.send('from-other-renderer', message);
}
});
});
7. 对象序列化
Electron 使用 HTML5 的 Structured Clone Algorithm 进行 IPC 通信时的对象序列化。
主进程(main.js):
ipcMain.on('send-object', (event, obj) => {
console.log(obj); // obj 是一个被序列化传递的对象
});
渲染进程(renderer.js):
ipcRenderer.send('send-object', { name: 'Electron', type: 'Framework' });
这个教程覆盖了 Electron 的各种 IPC 模式,提供了代码示例并解释了如何在不同的上下文中使用这些技术。通过这种方式,您可以灵活地实现各种应用程序功能,同时保持代码的安全性和高效性。