Electron进程间通信
使用Electron开发出来的桌面应用都是多进程
的,其中包含了一个主进程(Main)
和至少一个渲染进程(Renderer)
。
主进程控制整个应用的生命周期
,通过electron中的一些模块与GUI交互
,同时控制每一个渲染进程
。
渲染进程会在BrowserWindow对象
创建出的窗口中渲染出Web页面,每个渲染页面都运行在独立的进程中。
主进程与渲染进程之间通信
ipc模块 window.webContents
ipc模块包含ipcMain
和 ipcRenderer
两个模块,其中ipcMain在主进程中使用,ipcRenderer在渲染进程中使用,在使用之前,要使用require
引入对应的模块。
ipc模块中的方法:
ipcMain.on(msg, () => {})
:监听渲染进程发送的msg消息,并做出响应。ipcMain.once(msg, () => {})
:监听渲染进程发送的msg消息,并做出响应,但是监听到一次msg事件后自动移除这个监听器。ipcRenderer.on(msg, () => {})
:监听主进程发送的msg消息,并做出响应。ipcRenderer.once(msg, () => {})
:监听主进程发送的msg消息,并做出响应,但是监听到一次msg事件后自动移除这个监听器。ipcRenderer.send(msg, data)
:监听渲染进程向主进程发送msg异步消息,并携带参数data。ipcRenderer.sendSync(msg, data)
:监听渲染进程向主进程发送msg同步消息,并携带参数ipcRenderer.sentTo(webContentId, msg, data)
:监听渲染进程向具有webContentId的窗口发送消息ipcRenderer.sendToHost(msg, data)
:监听渲染进程向host页面上的 <webview>
元素发送消息
ipc模块还提供了删除指定监听器
和删除所有监听器
的方法:removeListener()
、removeAllListener()
,这两个方法在ipcMain和ipcRenderer这两个模块中的用法是一样的。
通过上面的几个监听器我们发现,单独使用ipc模块无法实现主进程主动向渲染进程发送消息
。所以我一般把BrowserWindow实例中的webContents
和ipc模块结合使用
一个主进程与渲染进程间通信的例子
// 在主进程中使用ipcMain
const { ipcMain, BrowserWindow } = require('electron');
window = new BrowserWindow({
width: 800,
height: 600
});
// 主进程主动向渲染进程发送消息
window.webContents.send('main webContents msg', data);
// 主进程接收渲染进程发送的消息,并通过回调函数做出响应
ipcMain.on('renderer ipc msg', (event, arg) => {
// TODO something
})
// 在渲染进程中使用ipcRender
const ipcRender = require('electron');
// 渲染进程中使用ipcRenderer.on接收主进程消息,并通过回调函数做出相应
ipcRenderer.on('main webContents msg', (event, arg) => {
// 在相应主进程事件时,通过ipcRenderer.send方法像主进程发送另一条消息
ipcRenderer.send('renderer ipc msg', data);
})
ipcRenderer发送的同步消息和异步消息
在上面列举的几个方法中,其中ipcRenderer发送消息的方法分为发送同步消息的方法ipcRenderer.send
和发送异步消息的方法ipcRenderer.sendSync
。主程序在监听到这两种不同方法的消息时,可以通过不同的方式给渲染进程返回消息:
// 渲染进程
// 渲染进程发送异步消息
ipcRenderer.send('msg', data);
// 渲染进程发送同步消息。 发送同步消息,任务未完成时会阻止其他操作
var message = ipcRenderer.sendSync('sync msg', data);
ipcMain.on('msg', (event, arg) => {
// 主进程监听到渲染进程发的异步消息后,通过event.sender.send()的方式进行响应,可以在渲染进程中使用ipcRenderer.on监听'return msg'消息
event.sender.send('return msg', data)
})
ipcMain.on('sync msg', (event, arg) => {
event.retuenValue = 'msg';
})
remote模块
在渲染进程中使用remote,可以调用主进程所提供的一些方法。(例如:dialog、menu等模块)
const { BrowserWindow } = require('electron').remote;
//通过remote模块,可以在渲染进程中调用BrowserWindow模块
let win = new BrowserWindow({ width: 800, height: 600});
win.loadURL('index.html');
渲染进程中使用remote模块返回的对象,都代表了主进程中的一个对象,一般称为远程对象
。调用远程对象的方法时,实际上是在想主进程发送同步消息。
比如上面的代码中,BrowserWindow实例是通过remote模块返回的,所以渲染进程中的BrowserWindow和win都是远程对象。在执行new BrowserWindow({...})
这段代码的时候,并没有在渲染进程中创建BrowserWindow实例的对象,而是在主进程中创建了BrowserWindow对象,并把这个对象返回到渲染进程中。
remote的方法和属性
remote.require(module)
:返回主进程中的对象remote.getCurrentWindow()
:返回此网页所属的窗口remote.getGlobal(name)
:返回主进程中name的全局变量remote.process
:返回主进程中的process对象
渲染进程之间通信
上面提到的通信方法,经过测试发现都无法在渲染进程之间直接通信,有时候我们开发中可以使用主进程作为中转
进行渲染进程间的通信:
// renderer process A
const { ipcRenderer } = require('electron');
ipcRenderer.send('A send msg', data);
// main process
const { ipcMain, BrowserWindow } = require('electron');
let win = new BrowserWindow({...});
ipcMain.on('A send msg', (event ,arg) => {
// TODO something
win.webContents.send('main send msg', data);
})
const { ipcRenderer } = require('electron');
ipcRenderer.on('main send msg', (event, arg) => {
// TODO something
})
除了上面这种需要main process中转的方式之外,还有一种方式能够实现渲染进程之间的直接通信:
// main process
// 两个窗口互相获取对方的窗口 id, 并发送给渲染进程
const { BrowserWindow} = require('electron');
let win1 = new BrowserWindow({...});
let win2 = new BrowserWindow({...});
win1.webContents.send('distributeIds',{
win2Id : win2.id
});
win2.webContents.send('distributeIds',{
win1Id : win1.id
});
// renderer process
const { remote } = require('electron').remote;
// fromId() 可以根据窗口id找到目标窗口
remote.BrowserWindow.fromId(win2Id).webContents.send('msg', data);
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbkgeb
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13