Electron進(jìn)程間通信的實(shí)現(xiàn)
使用Electron開(kāi)發(fā)出來(lái)的桌面應(yīng)用都是多進(jìn)程的,其中包含了一個(gè)主進(jìn)程(Main)和至少一個(gè)渲染進(jìn)程(Renderer)。
主進(jìn)程控制整個(gè)應(yīng)用的生命周期,通過(guò)electron中的一些模塊與GUI交互,同時(shí)控制每一個(gè)渲染進(jìn)程。
渲染進(jìn)程會(huì)在BrowserWindow對(duì)象創(chuàng)建出的窗口中渲染出Web頁(yè)面,每個(gè)渲染頁(yè)面都運(yùn)行在獨(dú)立的進(jìn)程中。
主進(jìn)程與渲染進(jìn)程之間通信
ipc模塊 + window.webContents
ipc模塊包含ipcMain和 ipcRenderer兩個(gè)模塊,其中ipcMain在主進(jìn)程中使用,ipcRenderer在渲染進(jìn)程中使用,在使用之前,要使用require引入對(duì)應(yīng)的模塊。
ipc模塊中的方法:
- ipcMain.on(msg, () => {}):監(jiān)聽(tīng)渲染進(jìn)程發(fā)送的msg消息,并做出響應(yīng)。
- ipcMain.once(msg, () => {}):監(jiān)聽(tīng)渲染進(jìn)程發(fā)送的msg消息,并做出響應(yīng),但是監(jiān)聽(tīng)到一次msg事件后自動(dòng)移除這個(gè)監(jiān)聽(tīng)器。
- ipcRenderer.on(msg, () => {}):監(jiān)聽(tīng)主進(jìn)程發(fā)送的msg消息,并做出響應(yīng)。
- ipcRenderer.once(msg, () => {}):監(jiān)聽(tīng)主進(jìn)程發(fā)送的msg消息,并做出響應(yīng),但是監(jiān)聽(tīng)到一次msg事件后自動(dòng)移除這個(gè)監(jiān)聽(tīng)器。
- ipcRenderer.send(msg, data):監(jiān)聽(tīng)渲染進(jìn)程向主進(jìn)程發(fā)送msg異步消息,并攜帶參數(shù)data。
- ipcRenderer.sendSync(msg, data):監(jiān)聽(tīng)渲染進(jìn)程向主進(jìn)程發(fā)送msg同步消息,并攜帶參數(shù)
- ipcRenderer.sentTo(webContentId, msg, data):監(jiān)聽(tīng)渲染進(jìn)程向具有webContentId的窗口發(fā)送消息
- ipcRenderer.sendToHost(msg, data):監(jiān)聽(tīng)渲染進(jìn)程向host頁(yè)面上的 <webview> 元素發(fā)送消息
ipc模塊還提供了刪除指定監(jiān)聽(tīng)器和刪除所有監(jiān)聽(tīng)器的方法:removeListener()、removeAllListener(),這兩個(gè)方法在ipcMain和ipcRenderer這兩個(gè)模塊中的用法是一樣的。
通過(guò)上面的幾個(gè)監(jiān)聽(tīng)器我們發(fā)現(xiàn),單獨(dú)使用ipc模塊無(wú)法實(shí)現(xiàn)主進(jìn)程主動(dòng)向渲染進(jìn)程發(fā)送消息。所以我一般把BrowserWindow實(shí)例中的webContents和ipc模塊結(jié)合使用
一個(gè)主進(jìn)程與渲染進(jìn)程間通信的例子
// 在主進(jìn)程中使用ipcMain const { ipcMain, BrowserWindow } = require('electron'); window = new BrowserWindow({ ?? ?width: 800, ?? ?height: 600 }); // 主進(jìn)程主動(dòng)向渲染進(jìn)程發(fā)送消息 window.webContents.send('main webContents msg', data); // 主進(jìn)程接收渲染進(jìn)程發(fā)送的消息,并通過(guò)回調(diào)函數(shù)做出響應(yīng) ipcMain.on('renderer ipc msg', (event, arg) => { ?? ?// TODO something })
// 在渲染進(jìn)程中使用ipcRender const ipcRender = require('electron'); // 渲染進(jìn)程中使用ipcRenderer.on接收主進(jìn)程消息,并通過(guò)回調(diào)函數(shù)做出相應(yīng) ipcRenderer.on('main webContents msg', (event, arg) => { ?? ?// 在相應(yīng)主進(jìn)程事件時(shí),通過(guò)ipcRenderer.send方法像主進(jìn)程發(fā)送另一條消息 ?? ?ipcRenderer.send('renderer ipc msg', data); })
ipcRenderer發(fā)送的同步消息和異步消息
在上面列舉的幾個(gè)方法中,其中ipcRenderer發(fā)送消息的方法分為發(fā)送同步消息的方法ipcRenderer.send和發(fā)送異步消息的方法ipcRenderer.sendSync。主程序在監(jiān)聽(tīng)到這兩種不同方法的消息時(shí),可以通過(guò)不同的方式給渲染進(jìn)程返回消息:
// 渲染進(jìn)程 // 渲染進(jìn)程發(fā)送異步消息 ipcRenderer.send('msg', data); // 渲染進(jìn)程發(fā)送同步消息。 發(fā)送同步消息,任務(wù)未完成時(shí)會(huì)阻止其他操作 var message = ipcRenderer.sendSync('sync msg', data);
ipcMain.on('msg', (event, arg) => { ?? ?// 主進(jìn)程監(jiān)聽(tīng)到渲染進(jìn)程發(fā)的異步消息后,通過(guò)event.sender.send()的方式進(jìn)行響應(yīng),可以在渲染進(jìn)程中使用ipcRenderer.on監(jiān)聽(tīng)'return msg'消息 ?? ?event.sender.send('return msg', data) }) ipcMain.on('sync msg', (event, arg) => { ?? ?event.retuenValue = 'msg'; })
remote模塊
在渲染進(jìn)程中使用remote,可以調(diào)用主進(jìn)程所提供的一些方法。(例如:dialog、menu等模塊)
const { BrowserWindow } = require('electron').remote; //通過(guò)remote模塊,可以在渲染進(jìn)程中調(diào)用BrowserWindow模塊 let win = new BrowserWindow({ width: 800, height: 600}); win.loadURL('index.html');
渲染進(jìn)程中使用remote模塊返回的對(duì)象,都代表了主進(jìn)程中的一個(gè)對(duì)象,一般稱為遠(yuǎn)程對(duì)象。調(diào)用遠(yuǎn)程對(duì)象的方法時(shí),實(shí)際上是在想主進(jìn)程發(fā)送同步消息。
比如上面的代碼中,BrowserWindow實(shí)例是通過(guò)remote模塊返回的,所以渲染進(jìn)程中的BrowserWindow和win都是遠(yuǎn)程對(duì)象。在執(zhí)行new BrowserWindow({...})這段代碼的時(shí)候,并沒(méi)有在渲染進(jìn)程中創(chuàng)建BrowserWindow實(shí)例的對(duì)象,而是在主進(jìn)程中創(chuàng)建了BrowserWindow對(duì)象,并把這個(gè)對(duì)象返回到渲染進(jìn)程中。
remote的方法和屬性
- remote.require(module):返回主進(jìn)程中的對(duì)象
- remote.getCurrentWindow():返回此網(wǎng)頁(yè)所屬的窗口
- remote.getGlobal(name):返回主進(jìn)程中name的全局變量
- remote.process:返回主進(jìn)程中的process對(duì)象
渲染進(jìn)程之間通信
上面提到的通信方法,經(jīng)過(guò)測(cè)試發(fā)現(xiàn)都無(wú)法在渲染進(jìn)程之間直接通信,有時(shí)候我們開(kāi)發(fā)中可以使用主進(jìn)程作為中轉(zhuǎn)進(jìn)行渲染進(jìn)程間的通信:
// 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中轉(zhuǎn)的方式之外,還有一種方式能夠?qū)崿F(xiàn)渲染進(jìn)程之間的直接通信:
// main process // 兩個(gè)窗口互相獲取對(duì)方的窗口 id, 并發(fā)送給渲染進(jìn)程 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() 可以根據(jù)窗口id找到目標(biāo)窗口 remote.BrowserWindow.fromId(win2Id).webContents.send('msg', data);
到此這篇關(guān)于Electron進(jìn)程間通信的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Electron進(jìn)程間通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue實(shí)現(xiàn)在data里引入相對(duì)路徑
這篇文章主要介紹了vue實(shí)現(xiàn)在data里引入相對(duì)路徑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06vue?退出登錄?清除localStorage的問(wèn)題
這篇文章主要介紹了vue?退出登錄?清除localStorage的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12vue組件值變化但不刷新強(qiáng)制組件刷新的問(wèn)題
這篇文章主要介紹了vue組件值變化但不刷新強(qiáng)制組件刷新的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06vue調(diào)用微信JSDK 掃一掃,相冊(cè)等需要注意的事項(xiàng)
這篇文章主要介紹了vue調(diào)用微信JSDK 掃一掃,相冊(cè)等需要注意的事項(xiàng),幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下2021-01-01基于vue實(shí)現(xiàn)網(wǎng)站前臺(tái)的權(quán)限管理(前后端分離實(shí)踐)
這篇文章主要介紹了基于vue實(shí)現(xiàn)網(wǎng)站前臺(tái)的權(quán)限管理(前后端分離實(shí)踐),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Vue input控件通過(guò)value綁定動(dòng)態(tài)屬性及修飾符的方法
這篇文章主要介紹了 Vue input控件通過(guò)value綁定動(dòng)態(tài)屬性及修飾符的方法,需要的朋友可以參考下2017-05-05vue打包后dist目錄下的index.html網(wǎng)頁(yè)顯示空白的問(wèn)題(兩種方案)
本文主要介紹了vue打包后dist目錄下的index.html網(wǎng)頁(yè)顯示空白的問(wèn)題,主要介紹了兩種方式,具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11