Electron进程之间的通信方式以及几个核心之间的关系

一、主进程 vs 渲染进程:核心对比

特性 主进程 (Main Process) 渲染进程 (Renderer Process)
运行环境 Node.js 环境 Chromium 浏览器环境
数量 唯一(整个应用只有一个) 多个(每个窗口对应一个)
权限 可调用所有 Node.js API 默认无法直接访问 Node.js(需 IPC 代理)
典型职责 创建窗口、系统菜单、托盘图标、文件操作 渲染界面、处理用户交互、前端逻辑
生命周期 控制应用启动/退出 窗口关闭时自动销毁

二、IPC 通信机制详解

1. 通信模式示意图

csharp 复制代码
[渲染进程]                            [主进程]
   │                                      │
   │   ipcRenderer.send('event', data)    │
   ├─────────────────────────────────────>│
   │                                      │
   │   ipcMain.on('event', handler)       │
   │<─────────────────────────────────────┤
   │   event.reply('reply-event', result) │
   │                                      │
   │   ipcRenderer.on('reply-event')      │
   │                                      │

2. 三种核心通信方式

方式 1:渲染进程 → 主进程(异步)

javascript 复制代码
// 渲染进程(通过预加载脚本暴露的方法)
window.electronAPI.sendMessage('Hello Main!');

// 主进程
ipcMain.on('send-message', (event, data) => {
  console.log(data); // 输出: Hello Main!
  event.reply('reply-message', 'Received!');
});

// 渲染进程接收回复
window.electronAPI.onReply((data) => {
  console.log(data); // 输出: Received!
});

方式 2:渲染进程 → 主进程(同步)

javascript 复制代码
// 渲染进程(谨慎使用,会阻塞界面!)
const result = window.electronAPI.syncMessage('Sync request');

// 主进程
ipcMain.on('sync-message', (event, data) => {
  event.returnValue = 'Sync response';
});

方式 3:主进程 → 渲染进程(主动推送)

javascript 复制代码
// 主进程
const win = new BrowserWindow(...);
win.webContents.send('update-data', { value: 42 });

// 渲染进程
window.electronAPI.onUpdateData((data) => {
  console.log(data.value); // 输出: 42
});

三、预加载脚本(Preload Script):安全桥梁

1. 核心作用图解

scss 复制代码
[Node.js 环境]                   [隔离的浏览器环境]
    主进程 <── IPC ──> 预加载脚本 <──> 渲染进程
                    (暴露有限 API)

2. 安全配置代码

javascript 复制代码
// 创建窗口时配置
new BrowserWindow({
  webPreferences: {
    preload: path.join(__dirname, 'preload.js'),
    contextIsolation: true, // 启用上下文隔离
    nodeIntegration: false  // 禁止直接访问 Node.js
  }
});

// preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
  sendMessage: (data) => ipcRenderer.send('send-message', data),
  onReply: (callback) => ipcRenderer.on('reply-message', callback)
});

四、核心关系与通信场景

1. 典型场景示例

场景 1:文件读取

javascript 复制代码
// 预加载脚本暴露方法
contextBridge.exposeInMainWorld('electronAPI', {
  readFile: (path) => ipcRenderer.invoke('read-file', path)
});

// 主进程处理
ipcMain.handle('read-file', async (event, path) => {
  return await fs.promises.readFile(path, 'utf-8');
});

// 渲染进程调用
const content = await window.electronAPI.readFile('data.txt');

场景 2:多窗口通信

javascript 复制代码
// 主进程维护窗口引用
const wins = new Map();

ipcMain.on('create-window', (event, id) => {
  const win = new BrowserWindow();
  wins.set(id, win);
});

ipcMain.on('send-to-window', (event, id, message) => {
  const targetWin = wins.get(id);
  targetWin.webContents.send('receive-message', message);
});

五、关键安全原则

  1. 永远不要这样做 ❌:

    html 复制代码
    <!-- 禁用安全配置的危险写法 -->
    <webview nodeIntegration></webview>
    <script>
      require('child_process').exec('rm -rf /'); // 恶意代码可执行系统命令!
    </script>

    运行 HTML

  2. 必须遵循的安全实践 ✅:

    • 始终启用 contextIsolation: true
    • 始终禁用 nodeIntegration: false
    • 通过预加载脚本白名单式暴露 API
    • 验证渲染进程发送的所有数据

六、性能优化建议

  1. 减少 IPC 调用频率

    合并多次操作为单次批处理:

    javascript 复制代码
    // 避免
    for (let i = 0; i < 100; i++) {
      window.electronAPI.updateItem(i);
    }
    
    // 推荐
    window.electronAPI.batchUpdate(items);
  2. 使用 SharedArrayBuffer 传递大数据

    适用于需要高频更新的大量数据(如图像处理):

    javascript 复制代码
    // 主进程
    const sharedBuffer = new SharedArrayBuffer(1024);
    win.webContents.send('shared-data', sharedBuffer);
    
    // 渲染进程
    const sameBuffer = receivedBuffer;

七、总结:核心关系图谱

css 复制代码
[主进程] 
  ├── 通过 BrowserWindow 创建 → [渲染进程]
  ├── 通过 ipcMain 监听 ←→ ipcRenderer 发送(IPC 通信) 
  └── 通过预加载脚本 → 安全暴露 API

[渲染进程]
  ├── 通过 window.electronAPI 调用受限功能
  └── 通过 webContents.send 接收主进程推送
相关推荐
曾经的你d19 小时前
【electron+vue】常见功能之——调用打开/关闭系统软键盘,解决打包后键盘无法关闭问题
vue.js·electron·计算机外设
2501_915373882 天前
Electron 打包与发布指南:让你的应用运行在 Windows、macOS、Linux
windows·macos·electron
Lysun0012 天前
electron 结合 react(cra创建的) 创建桌面应用和打包桌面应用
javascript·react.js·electron
Hugh_W3 天前
Electron 设置Chrome Flags
electron
未脱发程序员4 天前
分享一款开源的图片去重软件 ImageContrastTools,基于Electron和hash算法
前端·javascript·electron
2501_915373884 天前
打造一个 Markdown 编辑器:Electron 项目实战教程
javascript·electron·编辑器
2501_915373888 天前
Electron 从零开始:构建你的第一个桌面应用
前端·javascript·electron
2501_915373888 天前
Electron 架构详解:主进程与渲染进程的协作机制
electron
Acaibird.8 天前
腾讯元宝桌面客户端:基于Tauri的开源技术解析
ai·electron·tauri·跨平台开发
qq_589568109 天前
Electron学习+打包
前端·javascript·electron