electron进程间通信


Electron 应用程序的结构非常相似。 作为应用开发者,你将控制两种类型的进程:主进程 和 渲染器进程。 这类似于上文所述的 Chrome 的浏览器和渲染器进程。

主进程


每个 Electron 应用都有一个单一的主进程,作为应用程序的入口点。 主进程在 Node.js 环境中运行,这意味着它具有 require 模块和使用所有 Node.js API 的能力。

渲染器进程


每个 Electron 应用都会为每个打开的 BrowserWindow ( 与每个网页嵌入 ) 生成一个单独的渲染器进程。 洽如其名,渲染器负责 渲染 网页内容。 所以实际上,运行于渲染器进程中的代码是须遵照网页标准的 (至少就目前使用的 Chromium 而言是如此) 。

Preload 脚本


预加载(preload)脚本包含了那些执行于渲染器进程中,且先于网页内容开始加载的代码 。 这些脚本虽运行于渲染器的环境中,却因能访问 Node.js API 而拥有了更多的权限。

上下文隔离


上下文隔离功能将确保您的 预加载脚本 和 Electron的内部逻辑 运行在所加载的 webcontent网页 之外的另一个独立的上下文环境里。 这对安全性很重要,因为它有助于阻止网站访问 Electron 的内部组件 和 您的预加载脚本可访问的高等级权限的API 。

preload.js

// 在上下文隔离启用的情况下使用预加载
const { contextBridge } = require('electron')contextBridge.exposeInMainWorld('myAPI', {doAThing: () => {}
})

renderer.js

// 在渲染器进程使用导出的 API
window.myAPI.doAThing()

模式 1:渲染器进程到主进程(单向)ipcMain.on和ipcRenderer.send

主进程:ipcMain.on(eventname,callback)
接收渲染进程发过来的事件和参数,注意回调第一个参数是event,后面是参数

main

const { app, BrowserWindow, ipcMain } = require('electron')
//..............
ipcMain.on('set-title', (event, title) => {const webContents = event.senderconst win = BrowserWindow.fromWebContents(webContents)win.setTitle(title)})
//.................

渲染进程:ipcRenderer.send(eventname, arguments)
把ipcRender事件暴露给网页使用,附着到window上,因为默认上下文隔离,所以要使用contextBridge.exposeInMainWorld

preload

const { contextBridge, ipcRenderer } = require('electron')
//..................
contextBridge.exposeInMainWorld('electronAPI', {setTitle: (title) => ipcRenderer.send('set-title', title)
})
//省略

页面js中通过window对象获取暴露出的electronAPI调用事件,传递消息
window.electronAPI.???

render

const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {const title = titleInput.valuewindow.electronAPI.setTitle(title)
})

模式 2:渲染器进程到主进程(双向)ipcMain.handle和ipcRenderer.invoke

主进程:ipcMain.handle(eventname,callback)
main.js

const { app, BrowserWindow, ipcMain, dialog } = require('electron')
const path = require('path')async function handleFileOpen () {const { canceled, filePaths } = await dialog.showOpenDialog()if (!canceled) {return filePaths[0]}
}
ipcMain.handle('dialog:openFile', handleFileOpen)

染进程:ipcRenderer.invoke(eventname)
preload.js

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('electronAPI', {openFile: () => ipcRenderer.invoke('dialog:openFile')
})

renderer.js

const btn = document.getElementById('btn')
const filePathElement = document.getElementById('filePath')btn.addEventListener('click', async () => {const filePath = await window.electronAPI.openFile()filePathElement.innerText = filePath
})

注意 由于ipcRenderer.invoke()返回的是一个promise对象,想要获取到返回的值,需要使用.then()或者await获取返回值.

模式 3:主进程到渲染器进程 (单双向)mainWindow.webContents.send和ipcRenderer.on

将消息从主进程发送到渲染器进程时,需要指定是哪一个渲染器接收消息。 消息需要通过其 WebContents 实例发送到渲染器进程。 此 WebContents 实例包含一个 send 方法,其使用方式与 ipcRenderer.send 相同。
主进程:
main.js

1. 使用 webContents 模块发送消息
对于此演示,我们需要首先使用 Electron 的 Menu 模块在主进程中构建一个自定义菜单,该模块使用 webContents.send API 将 IPC 消息从主进程发送到目标渲染器。

  const mainWindow = new BrowserWindow({webPreferences: {preload: path.join(__dirname, 'preload.js')}})mainWindow.webContents.send('update-counter', -1)

渲染进程:
preload.js

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('electronAPI', {onUpdateCounter: (callback) => ipcRenderer.on('update-counter', callback)
})

rederer.js

const counter = document.getElementById('counter')window.electronAPI.onUpdateCounter((_event, value) => {const oldValue = Number(counter.innerText)const newValue = oldValue + valuecounter.innerText = newValue
})

可选:返回一个回复
对于从主进程到渲染器进程的 IPC,没有与 ipcRenderer.invoke 等效的 API。 不过,您可以从 ipcRenderer.on 回调中将回复发送回主进程。
我们可以对前面例子的代码进行略微修改来演示这一点。 在渲染器进程中,使用 event 参数,通过 counter-value 通道将回复发送回主进程。

renderer.js (Renderer Process)

const counter = document.getElementById('counter')window.electronAPI.onUpdateCounter((event, value) => {const oldValue = Number(counter.innerText)const newValue = oldValue + valuecounter.innerText = newValueevent.sender.send('counter-value', newValue)
})

在主进程中,监听 counter-value 事件并适当地处理它们。
main.js (Main Process)

// ...
ipcMain.on('counter-value', (_event, value) => {console.log(value) // will print value to Node console
})
// ...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/692279.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vivado仿真readmemb函数相对路径

目前常用的vivado工程的结构如下所示 prj-name|-xxx|-prj.sim|-sim_1|-behav|-modelsim|-tb_prj.do|-xsim|-prj.srcs|-sim_1|-new|-tb_prj.v|-tb_prj_mem.txt一般来说我们创建的testbench文件和新建的txt文件都会放在srcs->sim_1->new这个路径下面,但是我们在…

2024年4月17日华为春招实习试题【三题】-题目+题解+在线评测,2024.4.17,华为机试

2024年4月17日华为春招实习试题【三题】-题目题解在线评测 🔮题目一描述:扑克牌消消乐输入描述输出描述样例一样例二Limitation解题思路一:模拟,遇到连续3张相同牌号的卡牌,直接删除解题思路二:栈解题思路三…

3D 生成重建010-SyncDreamer从单视图生成一致性的多视图

3D 生成重建010-SyncDreamer从单视图生成一致性的多视图 文章目录 0论文工作1论文方法2 效果 0论文工作 在zero123中,首先探索了给2d图像扩散模型注3d空间感知能力。可以将原图输入模型,通过相机位置的相对偏移生成对应的新视图。 这篇论文就是在zero1…

PyQt5中的Label标签

文章目录 1. 简介1.1 常用方法:1.2 常用信号 2. 常用方法使用案例13. 常用方法使用案例24. 常用信号使用案例 1. 简介 在PyQt5中,QLabel控件是用于显示文本或图像的常用控件之一。以下是一些常用的QLabel控件的方法和信号: 1.1 常用方法&am…

程序员工作中常见问题,你遇到过几个?

在赛博朋克2077玩后感中,我提到,即便是在严谨的机制下,依然可能出现让人匪夷所思或是贻笑大方的问题。 那么今天,就以后端程序员的视角,盘点下从设计开发到上线的常见问题,看看大家中过几个。 01 设计与开…

01、什么是ip、协议、端口号知道吗?计算机网络通信的组成是什么?

声明:本教程不收取任何费用,欢迎转载,尊重作者劳动成果,不得用于商业用途,侵权必究!!! 目录 前言 计算机网络 网络ip地址 网络协议 网络端口号 前言 最近有个项目要用到相关文章…

mysql中的页和行

页 行即表中的真实行,‘行式数据库’的由来 虽然MySQL的数据文件(例如.ibd文件)中的数据页在物理上是通过链表连接的,但是在逻辑上,MySQL使用B树来组织和访问数据。 行:主要是dynamic类型

Docker尚硅谷_高级篇

Docker尚硅谷 高级篇一、Dockerfile1.1 Dockerfile1.2 构建过程1.3 Dockerfile保留字1.3 构建镜像1.4 虚悬镜像 二、Docker发布微服务2.1 搭建SpringBoot项目2.2 发布微服务项目到Docker容器 三、Docker网络3.1 Docker网络3.2 docker网络命令3.3 Docker网络模式3.4 docker03.5 …

MySQL性能优化(提升数据库性能的措施)

万物皆有裂痕,那是光照进来的地方。大家好,今天给大家分享一下关于MySQL性能优化,在处理大型数据集和高负载情况下,MySQL数据库的性能优化是至关重要的。通过合理的调优策略,可以有效提高数据库的响应速度和稳定性。本…

Jsp+Servlet实现图片上传和点击放大预览功能(提供Gitee源码)

前言:在最近老项目的开发中,需要做一个图片上传和点击放大的功能,在Vue和SpringBoot框架都有现成封装好的组件和工具类,对于一些上世纪的项目就没这么方便了,所以需要自己用原生的代码去编写,这里分享一下我…

VMamba模型

VMamba模型 摘要Abstract1. VMamba模型1.1 文献摘要1.2 研究背景1.3 状态空间模型(SSM)1.4 VMamba架构1.5 实验1.5.1 ImageNet-1K 上的图像分类1.5.2 COCO 上的物体检测 总结2. pytorch练习 摘要 Abstract 1. VMamba模型 文献出处:VMamba:…

Idea入门:一分钟创建一个Java工程

一,新建一个Java工程 1,启动Idea后,选择 [New Project] 2,完善工程信息 填写工程名称,根据实际用途取有意义的英文名称选择Java语言,可以看到还支持Kotlin、Javascript等语言选择包管理和项目构建工具Mav…