上一篇 electron主进程和渲染进程
下一篇 electron API
目标
: 掌握进程间通讯
进程间通讯的常见情况
-
通知事件
: 例如渲染进程通知主进程创建一个提醒 -
数据传输
: 例如某个页面需要获得当前的内存数据,需要主进程进行数据传输 -
共享数据
: 例如公共的用户信息共享
IPC模块通讯
- electron 提供了IPC通讯模块, 即主进程的
pcMain
和渲染进行的ipcRenderer
进行通讯 -
ipcMain
和ipcRenderer
都是Eventmitter对象
进程通讯实例(渲 => 主)
-
Callback 写法
ipcRenderer.send(channel, ...args)
ipcMain.on(channel, handler)
// 渲染进程 ipc.js
const { ipcRenderer } = require('electron');
window.onload = function () {
// 渲染进程发出事件 channel, 参数 1,2,3
ipcRenderer.send("channel1", 1, 2, 3);
}
// 主进程 main.js
const { app, BrowserWindow, ipcMain } = require('electron');
let win = null;
app.on("ready", () => {
win = new BrowserWindow({
width: 800,
height: 500,
webPreferences: { nodeIntegration: true }
})
win.loadFile("index.html");
// 主进程监听事件
ipcMain.on("channel1", (e, a, b, c) => {
// 乱码, 在package.json中添加 "start": "chcp 65001 && electron ."
console.log("监听到渲染进程的发出的事件(callback)", a, b, c);
})
win.on("close", () => {
win = null;
})
})
//***********************************************************************************
注意点:
如果控制台输出中文乱码,可以在package.json中添加 "start": "chcp 65001 && electron ."
使用 npm start 启动项目
//***********************************************************************************
结果
-
Promise 写法(Electron 7.0 之后, 处理请求 + 响应模式)
ipcRenderer.invoke(channel, ...args)
ipcMain.handle(channel, handler)
// 渲染进程 ipc.js
// 发出事件
ipcRenderer.invoke("channel2", 1, 2, 3);
// 主进程 main.js
ipcMain.handle("channel2", (e, a, b, c) => {
console.log("监听到渲染进程的发出的事件(Promise)", a, b, c)
})
结果
进程通讯实例(主 => 渲)
ipcRenderer.on(channel, handler) (渲)
webContents.send(channel) (主)
ipcRenderer.on("channel3", () => {
alert("渲染进程接收到主进程事件");
})
// 主进程向渲染进程通讯
setTimeout(() => {
win.webContents.send("channel3");
}, 1000)
END
进程通讯实例(页面间通讯)
- 通知事件
electron 5 之前: 通过主进程转发(即:渲 => 主 => 渲)
electron 5 之后: ipcRenderer.sendTo
// 主进程 main.js
const { app, BrowserWindow, ipcMain } = require('electron');
let win1 = null;
let win2 = null;
app.on("ready", () => {
win1 = new BrowserWindow({
width: 800,
height: 500,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true
}
})
win2 = new BrowserWindow({
width: 800,
height: 500,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true
}
})
// 保存win2窗口的 id
global.sharedObject = {
win2WebContentsId: win2.webContents.id
}
win2.loadFile("page2.html");
win1.loadFile("page1.html");
win1.on("close", () => { win1 = null;})
win2.on("close", () => {win2 = null;})
})
---- --- ---- --- --- ---- -- --- - -- - - -- - - ---- --- -- -- - - -- - - -- - -
// page1页面js
const { ipcRenderer, remote } = require('electron');
// 获取page2页面的 id
let { win2WebContentsId } = remote.getGlobal("sharedObject");
// 根据页面 id 发送事件
ipcRenderer.sendTo(win2WebContentsId, "page1Event", 1, 2, 3);
---- --- ---- --- --- ---- -- --- - -- - - -- - - ---- --- -- -- - - -- - - -- - -
// page2页面
const { ipcRenderer } = require('electron');
ipcRenderer.on("page1Event", (e, a, b, c) => {
alert("我是page2, 监听到 page1Event", a, b, c);
})
******************************************************************
注意点:
electron 10下,remote默认关闭,需要手动开启
enableRemoteModule: true, // 打开remote模块
******************************************************************
结果
- 数据共享
Web技术(localStorage、sessionStorage、indexedDB)
使用remote(不推荐)
网友评论