electron 渲染进程调用主进程_Electron 主进程与渲染进程通信

2ff34e647e2e3cdfd8dca593e17d9b0a.png

主进程与渲染进程

Electron 中,从 package.json 的 main 载入的 js 件就是主进程,由主进程加载出来的页面就是渲染进程。

主进程负责掌管所有的 Web 页面和它们相应的渲染进程,包括原生的组件操作。而在 Electron 里的每个页面都有它自己的进程,叫作渲染进程,它主要负责 Web 的渲染。

主进程通过实例化 BrowserWindow,每个 BrowserWindow 实例都在它自己的渲染进程内返回一个 web 页面。当 BrowserWindow 实例销毁时,相应的渲染进程也会终止。

在渲染进程中不允许调用原生 GUI 相关的 API,那是因为在网页(渲染进程)中使用原生 GUI 很危险,易造成内存泄露。

利用 ipcMain 与 ipcRenderer 通信

ipcMain 模块是类 EventEmitter 的实例。当在主进程中使用它的时候,它控制着由渲染进程发送过来的异步或同步消息,从渲染进程发送过来的消息将触发事件,同样也可以从主进程向渲染进程发送消息,事件的对称的。

因此,可以通过事件的订阅或与发布,实现主进程与渲染进程之间的通信。在主进程里,使用 ipcMain 向渲染线程发出通知1

2

3

4

5

6

7

8

9

10

11

12const ipcMain = require('electron').ipcMain;

ipcMain.on('asynchronous-message', function(event, arg){

console.log(arg); // prints "ping"

event.sender.send('asynchronous-reply', 'pong');

});

// 同步通信

ipcMain.on('synchronous-message', function(event, arg){

console.log(arg); // prints "ping"

event.returnValue = 'pong';

});在渲染进程里,使用 ipcRenderer 向主线程发出通知1

2

3

4

5

6

7

8

9

10

11const ipcRenderer = require('electron').ipcRenderer;

// 发一个同步消息给所以 synchronous-message 监听者

console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"

// 监听

ipcRenderer.on('asynchronous-reply', function(event, arg){

console.log(arg); // prints "pong"

});

// 发一个异步消息给所有 asynchronous-message 监听者

ipcRenderer.send('asynchronous-message', 'ping');

注意的地方,在 ipcMain 里是不能主动向 ipcRenderer 发消息的,只能在 event 里回消息。

ipcMain API

ipcMain 模块有以下方法:ipcMain.on(channel, listener) 监听 channel, 当新消息到达,将通过 listener(event, args…) 调用 listener。

ipcMain.once(channel, listener) 监听一次(一次性)。

ipcMain.removeListener(channel, listener) 取消监听。

ipcMain.removeAllListeners([channel]) 取消全部监听。

而在 listener 里 event 有以下属性:event.returnValue 将此设置为在一个同步消息中返回的值。

event.sender 返回发送消息的 webContents ,你可以调用 event.sender.send 来回复异步消息。

ipcRenderer API

ipcRenderer 模块有以下方法:ipcRenderer.on(channel, listener) 监听 channel, 当新消息到达,将通过 listener(event, args…) 调用 listener。

ipcRenderer.once(channel, listener) 监听一次(一次性)。

ipcRenderer.removeListener(channel, listener) 取消监听。

ipcRenderer.removeAllListeners([channel]) 取消全部监听。

ipcRenderer.send(channel[, arg1][, arg2][, …]) 通过 channel 向主进程发送异步消息,也可以发送任意参数。

ipcRenderer.sendSync(channel[, arg1][, arg2][, …]) 通过 channel 向主进程发送同步消息,也可以发送任意参数。

ipcRenderer.sendToHost(channel[, arg1][, arg2][, …]) 它的事件将发往 host page 的 元素,而不是主进程。

利用 remote 通信

remote 模块提供了一种在渲染进程(网页)到主进程之间进行进程间通讯(IPC)的简便途径。注意: 反向操作(从主进程访问渲染进程),可以使用 webContents.executeJavascript.

Electron 中与 GUI 相关的模块(如 dialog, menu 等)只存在于主进程,而不在渲染进程中。为了能从渲染进程中使用它们,需要用 ipc 模块来给主进程发送进程间消息。使用 remote 模块,可以调用主进程对象的方法,而无需显式地发送进程间消息。

remote 模块返回的每个对象(包括函数)都代表了主进程中的一个对象。

在主进程中的内置模块已经被添加为 remote 模块中的属性,所以可以直接像使用 electron 模块一样直接使用它们。1

2

3

4

5

6// 在渲染进程文件里

const remote = require('electron').remote;

const BrowserWindow = remote.BrowserWindow;

var win = new BrowserWindow({ width: 800, height: 600 });

win.loadURL('https://github.com');

remote API

remote 模块有以下方法:remote.require(module) 返回在主进程中执行 require(module) 所返回的对象。

remote.getCurrentWindow() 返回该网页所属的 BrowserWindow 对象。

remote.getCurrentWebContents() 返回该网页的 WebContents 对象。

remote.getGlobal(name) 返回在主进程中名为 name 的全局变量(即 global[name])。

remote.process 返回主进程中的 process 对象。等同于 remote.getGlobal('process') 但是有缓存。

参考资料

你可能感兴趣的:(electron,渲染进程调用主进程)