在 Electron 中,渲染进程之间无法直接通信,必须通过主进程作为中介。以下是详细的步骤和示例:
通信步骤
- 渲染进程A 发送消息至 主进程。
- 主进程 接收消息并转发至 渲染进程B。
- 渲染进程B 接收并处理消息。
示例代码
主进程(main.js)
javascript
const { app, BrowserWindow, ipcMain } = require('electron');
let mainWindow, secondaryWindow;
app.whenReady().then(() => {
// 创建主窗口
mainWindow = new BrowserWindow({ webPreferences: { nodeIntegration: true, contextIsolation: false } });
mainWindow.loadFile('main.html');
// 创建次窗口
secondaryWindow = new BrowserWindow({ webPreferences: { nodeIntegration: true, contextIsolation: false } });
secondaryWindow.loadFile('secondary.html');
// 监听来自主窗口的消息
ipcMain.on('message-from-main', (event, data) => {
// 转发给次窗口
secondaryWindow.webContents.send('message-to-secondary', data);
});
// 监听来自次窗口的消息
ipcMain.on('message-from-secondary', (event, data) => {
// 转发给主窗口
mainWindow.webContents.send('message-to-main', data);
});
});
主窗口渲染进程(main.html/main.js)
xml
<button id="sendBtn">发送消息到次窗口</button>
<script>
const { ipcRenderer } = require('electron');
document.getElementById('sendBtn').addEventListener('click', () => {
const data = { text: '来自主窗口的消息' };
ipcRenderer.send('message-from-main', data); // 发送到主进程
});
// 接收来自次窗口的消息
ipcRenderer.on('message-to-main', (event, data) => {
console.log('主窗口收到:', data.text);
});
</script>
次窗口渲染进程(secondary.html/secondary.js)
xml
<button id="sendBtn">发送消息到主窗口</button>
<script>
const { ipcRenderer } = require('electron');
document.getElementById('sendBtn').addEventListener('click', () => {
const data = { text: '来自次窗口的消息' };
ipcRenderer.send('message-from-secondary', data); // 发送到主进程
});
// 接收来自主窗口的消息
ipcRenderer.on('message-to-secondary', (event, data) => {
console.log('次窗口收到:', data.text);
});
</script>
动态管理多个窗口
若需处理多个动态窗口,主进程需维护窗口引用:
主进程优化(main.js)
csharp
const windows = new Map(); // 存储窗口ID和WebContents
function createWindow() {
const win = new BrowserWindow({ webPreferences: { nodeIntegration: true, contextIsolation: false } });
windows.set(win.id, win.webContents); // 保存窗口ID和WebContents
win.on('closed', () => {
windows.delete(win.id); // 窗口关闭时移除
});
return win;
}
// 监听任意渲染进程的消息并动态转发
ipcMain.on('send-to-window', (event, { targetId, data }) => {
const target = windows.get(targetId);
if (target) target.send('direct-message', data);
});
渲染进程发送消息
javascript
// 获取当前窗口ID(需主进程在创建窗口时传递)
const windowId = require('electron').remote.getCurrentWindow().id;
// 发送到目标窗口(如ID为2的窗口)
ipcRenderer.send('send-to-window', {
targetId: 2,
data: { text: '动态路由消息' }
});
// 接收其他窗口的消息
ipcRenderer.on('direct-message', (event, data) => {
console.log('收到来自窗口', event.sender.id, '的消息:', data.text);
});
关键点总结
- 主进程中介:所有渲染进程通信必须通过主进程转发。
- IPC 通道 :使用
ipcMain
和ipcRenderer
监听和发送消息。 - WebContents 引用 :主进程通过
webContents.send()
向指定窗口发送消息。 - 动态窗口管理 :使用
Map
或Set
存储窗口引用,实现灵活的路由。