Electron 主进程、渲染进程及进程间的通信
简介
Electron是由GIthub开发,用HTML、CSS、JS来构建跨平台桌面应用程序的一个开源库。Electron将Chromium和Nodejs合并到同一个运行时环境中,并将其打包为Mac、Windows、Linux系统下的应用。可以将其看作是一个由JS控制的迷你版的Chromium浏览器。
主进程、渲染进程
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提供了集中渲染进程和主进程通信的方式:
- 使用ipcMain和ipcRenderer模块;
- 直接在渲染进程中使用remote模块;
- 主进程向渲染进程发送消息;
- 渲染进程之间的通信。
目前项目中用到的通信方式为第一种,此文只详细介绍第一种。
使用ipcMain和ipcRenderer模块
在渲染进程中使用ipcRenderer模块向主进程发送消息,主进程中ipcMain接收消息,进行操作,如需反馈,则通知渲染进程,渲染进程根据接收的内容执行相应的操作:
// 渲染进程
const ipcRenderer = require('electron').ipcRenderer;
// 同步消息使用sendSync方法,在发出瞬间即可接收到响应内容
console.log(ipcRenderer.sendSync('synchronous-message', 'ping')); // prints "pong"ipcRenderer.on('asynchronous-reply', function(event, arg) {console.log(arg); // prints "pong"
});
// 异步消息使用send方法,需要监听异步事件才能得到响应
ipcRenderer.send('asynchronous-message', 'ping');
// 主进程
const 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';
});
⚠️ 切忌用ipc传递大量的数据,会有很大的性能问题,严重会让整个应用卡住。
ipcMain模块 监听消息 相关函数
/**
* 监听 channel 事件,当新消息到达,通过listener(event, args...)调用listener
* @param {String} channel
* @param {Function} listener
*/
ipcMain.on(channel, listener);/**
* 同上,但只触发一次,触发后自动取消绑定
* @param {String} channel
* @param {Function} listener
*/
ipcMain.once(channel, listener);/**
* 为特定的 channel 从监听队列中删除特定的 listener 监听者
* @param {String} channel
* @param {Function} listener
*/
ipcMain.removeListener(channel, listener);/**
* 删除所有监听者,或特指的 channel 的所有监听者
* @param {String} channel
* @param {Function} listener
*/
ipcMain.removeAllListeners([channel]);
ipcRenderer模块 监听消息 相关函数
/**
* 监听 channel 事件,当新消息到达,通过listener(event, args...)调用listener
* @param {String} channel
* @param {Function} listener
*/
ipcRenderer.on(channel, listener);/**
* 同上,但只触发一次,触发后自动取消绑定
* @param {String} channel
* @param {Function} listener
*/
ipcRenderer.once(channel, listener);/**
* 为特定的 channel 从监听队列中删除特定的 listener 监听者
* @param {String} channel
* @param {Function} listener
*/
ipcRenderer.removeListener(channel, listener);/**
* 删除所有监听者,或特指的 channel 的所有监听者
* @param {String} channel
* @param {Function} listener
*/
ipcRenderer.removeAllListeners([channel]);
ipcRenderer模块 发送消息 相关函数
/**
* 通过 channel 向主进程发送异步消息,也可以发送任意参数.参数会被JSON序列化,之后就不会包含函数或原型链。主进程通过使用 ipcMain 模块来监听 channel,从而处理消息.通过 event.sender.send() 来响应.
* @param {String} channel
* @param {} [arg]
*/
ipcRenderer.send(channel[, arg1][, arg2][, ...]);/**
* 通过 channel 向主进程发送同步消息,也可以发送任意参数.参数会被JSON序列化,之后就不会包含函数或原型链.主进程通过使用 ipcMain 模块来监听 channel,从而处理消息, 通过 event.returnValue 来响应.
* @param {String} channel
* @param {} [arg]
*/
// ⚠️发送同步消息将会阻塞整个渲染进程,除非你知道你在做什么,否则就永远不要用它 .
ipcRenderer.sendSync(channel[, arg1][, arg2][, ...]);/**
* 类似 ipcRenderer.send ,但是它的事件将发往 host page 的 <webview> 元素,而不是主进程.
* @param {String} channel
* @param {} [arg]
*/
ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...]);
直接在渲染进程中使用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');
参考:我眼中的 Electron Electron入门之ipcMain,ipcRenderer
Electron 主进程、渲染进程及进程间的通信相关推荐
- Electron主进程渲染进程间通信的四种方式
在electron中进程使用 ipcMain 和 ipcRenderer 模块,通过开发人员定义的"通道"传递消息来进行通信.新的版本中electron推荐使用上下文隔离渲染器进程 ...
- electron 主进程与渲染进程通讯
主进程和渲染器进程 Electron 有两种进程:主进程和渲染进程. 主进程通过创建 BrowserWindow 实例来创建 网页. 每一个 BrowserWindow 实例在其渲染过程中运行网页, ...
- Electron主进程和渲染进程之间通信
Electron发送和接收数据用到的是 ipcMain 和 ipcRenderer 两个对象: ipcMain 是用在主进程中的: ipcRenderer 是用在渲染进程中的. 主进程用win.web ...
- 第八节 Electron主进程和渲染进程之间的通信
系列文章目录 第一节 electron 介绍 第二节 创建electron项目并启动 第三节 Electron运行流程 . 主进程渲染进程并使用nodejs 第四节 Electron 调用H5事件结合 ...
- electron 主进程与渲染进程 渲染进程与渲染进程 之间的通信
主进程与渲染进程之间的通信 这是渲染进程 // 渲染进程执行主进程里面的方法,主进程给渲染进程反馈处理结果 . var sendreplayDom=document.querySelector('#s ...
- Electron怎样进行渲染进程调试和使用浏览器和VSCode进行调试
场景 用HTML和CSS和JS构建跨平台桌面应用程序的开源库Electron的介绍以及搭建HelloWorld: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/a ...
- electron 打开调试_Electron教程:菜鸟学Electron 主进程调试
浏览器窗口的开发工具仅能调试渲染器的进程脚本(比如 web 页面).为了提供一个可以调试主进程的方法,Electron 提供了 --debug 和 --debug-brk开关. 命令行开关 使用如下的 ...
- 微信小游戏直播在Android端的跨进程渲染推流实践
本文由微信开发团队工程师"virwu"分享. 1.引言 近期,微信小游戏支持了视频号一键开播,将微信升级到最新版本,打开腾讯系小游戏(如跳一跳.欢乐斗地主等),在右上角菜单就可以看 ...
- python互斥锁原理_python并发编程之多进程1------互斥锁与进程间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- Linux系统编程(三)进程间的通信
Linux系统编程(三)进程间的通信 一.为什么需要进程之间的通信(IPC)? 二.管道 1.概念 2.特质 3.原理 4.局限性 5.代码 2.读入数据 三.共享存储映射 注意事项 父子进程通信 一 ...
最新文章
- 超级干货:3个性能监控和优化命令详解
- 剑指offer18.删除链表结点(添加dummy,next域结点指向head)
- struts2中result的type属性详解
- TCP/IP详解--TCP/IP中三次握手 四次握手状态分析
- OpenCV delaunay三角剖分和voronoi镶嵌的实例(附完整代码)
- linux之vim/vi快速复制多行内容的快捷键
- Abstract Self-Balancing Binary Search Tree
- 程序员学历要求越来越高,薪酬天花板犹如发际线,原因很简单!
- 基于函数的二叉树的描述
- srs流媒体服务器windows_基于SRS构建的直播平台的监控系统的搭建思路与实现方法...
- 系统学习 TypeScript(五)——联合类型
- 《刀塔传奇》付费设计分析
- [总结]RTMP流媒体技术零基础学习方法
- GET和POST 区别
- 四旋翼电池、电机、螺旋桨选型与搭配
- 块存储、文件存储、对象存储的区别
- 计算机科学的稿费有多少,写作近两年,稿费3000+,老实人告诉你为什么那么多人写作能月入30000...
- 系统非功能需求(质量属性)
- win10下如何为jdk配置环境变量
- 他教全世界程序员怎么写好代码,答案写在这里!