一、前端需要看的elecron的基本知识
Electron打包的应用包含两个部分:Electron的环境(node) — 主进程、web渲染环境 — 渲染进程。
Electron中,入口是js文件(通常为package.json里的main脚本),运行此文件的进程即为主进程,在主进程中使用BrowserWindow模块可以创建并管理web页面,也就是应用的GUI。
const {BrowserWindow} = require('electron');
// 创建浏览器窗口
let win = new BrowserWindow({width: 320, height: 572, resizable: true});
// 加载本地的文件
win.loadURL('file://' + __dirname + '/index.html');
// 打开调试窗口
win.webContents.openDevTools();
在主进程创建的每个web页面都运行着自己的进程,即渲染进程,渲染进程各自独立。
主进程和渲染进程之间是相互隔离的,无法直接进行数据通信。
Web页面因为安全限制,不能直接访问原生的GUI资源,Electron也一样,渲染进程如果想要进行原生的GUI操作,必须和主进程通信,请求相应的GUI操作。
Electron提供了集中渲染进程和主进程通信的方式:
1使用ipcMain和ipcRenderer模块;
2直接在渲染进程中使用remote模块;
3主进程向渲染进程发送消息;
4渲染进程之间的通信。
二、关于渲染进程与主进程通信
1、
渲染进程中
const { ipcRenderer } = require('electron')
// 同步消息 调用的结果就是回复
console.log(ipcRenderer.sendSync('同步消息', '同步参数')) // prints "我回复了同步消息"
// 因为是异步,所以在这里等待消息的回复
ipcRenderer.on('asynchronous-reply', (event, arg) => {
console.log(arg) // prints "pong"
})
// 异步消息发送
ipcRenderer.send('asynchronous-message', 'ping')
主进程中
const { ipcMain } = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.reply('asynchronous-reply', 'pong')
})
ipcMain.on('同步消息', (event, arg) => {
console.log(arg) // prints "同步参数"
event.returnValue = '我回复了同步消息'
})
2、这种我暂时没用过,event.sender.send也可以回复异步消息
使用 ipc 以异步方式在进程之间发送消息是首选方法, 因为它会在完成时返回, 而不会阻止同一进程中的其他操作.
此示例将从此进程(渲染器)发送异步消息 "Ping" 到主进程, 然后主进程回答 "Pong".
renderer.js 如下:
// 异步消息使用send方法,需要监听异步事件才能得到响应
ipcRenderer.send('asynchronous-message', 'ping');
main.js 如下:
ipcMain.on('asynchronous-message', function(event, arg) {
console.log(arg); // prints "ping"
// 回应异步消息
event.sender.send('asynchronous-reply', 'pong');
});
3、同步与异步的区别
三、
直接在渲染进程中使用remote模块
remote 模块可以直接获取主进程中的模块。
// 在渲染进程打开提示对话框
const {dialog} = require('electron').remote
dialog.showMessageBox({ opts });
四、
主进程向渲染进程发送消息
this.webviewWindow.webContents.send('ping');
五、
渲染进程间通信
如果数据不需要实时性,只是渲染进程之间数据的共享,那么使用官方建议即可。如果要求实时性,需要配合前几种种方式实现。
// 主进程
// 两个窗口互相获取对方的窗口 id, 并发送给渲染进程
win1.webContents.send('distributeIds',{
win2Id : win2.id
});
win2.webContents.send('distributeIds',{
win1Id : win1.id
});
// 渲染进程
// 通过 id 得到窗口
remote.BrowserWindow.fromId(win2Id).webContents.send('someMsg', 'someThing');