這篇筆記主要解決的問題是Electron的主進程與渲染進程之間的通信.
使用ipcMain和ipcRenderer
// 來自官方的示例
const {ipcMain} = require('electron')
ipcMain.on('asynchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.sender.send('asynchronous-reply', 'pong')
})
ipcMain.on('synchronous-message', (event, arg) => {
console.log(arg) // prints "ping"
event.returnValue = 'pong'
})
要點:
- 渲染進程可以通過
ipcRenderer向主進程發送消息 - 主進程通過
ipcMain監聽來自渲染進程的消息. 並根據消息類型執行不同的操作 - 主進程的回調方法包含
event和arg兩個參數.arg對象中保存了渲染進程傳遞的參數. 通過event.sender對象,主進程可以直接向渲染進程發送返回消息. 如果主進程執行的同步方法,還可以通過設置event.returnValue來獲取返回值.
使用 electron.remote 模塊
在渲染進程中,可以通過const {remote} = require('electron')來獲取到remote對象. 通過這個對象可以允許渲染進程訪問主進程的模塊.
const {BrowserWindow} = require('electron').remote;
let win = new BrowserWindow({width: 800, height: 600});
win.loadURL('https://xxx.com');
同樣的,我們也可以通過remote對象訪問到app對象。這樣我們就可以訪問到我們在主進程中掛載到electron.app對象上的方法。
// 主進程
const { app } = require('electron');
const utils = require('./utils');
app.utils = utils; // 將在 Electron 層實現的接口綁定到 app 上
// 渲染進程
const { remote } = require('electron');
function() {
// remote.app.utils 對象與主進程中的utils對象是一樣的。
remote.app.utils.test();
}
要點:
通過remote對象,我們可以不必發送進程間消息來進行通信。但實際上,我們在調用遠程對象的方法、函數或者通過遠程構造函數創建一個新的對象,實際上都是在發送一個同步的進程間消息(官方文檔 上說這類似於JAVA中的RMI)。
也就是說,remote方法只是不用讓我們顯式的寫發送進程間的消息的方法而已。在上面通過remote模塊創建BrowserWindow的例子里。我們在渲染進程中創建的BrowserWindow對象其實並不在我們的渲染進程中,它只是讓主進程創建了一個BrowserWindow 對象,並返回了這個相對應的遠程對象給了渲染進程。
