Electron 进程通信

预加载(preload)脚本只能访问部分 Node.js API,但是主进程可以访问全部API。此时,需要使用进程通信。
比如,在preload.js中,不能访问__dirname,不能使用 Node 中的 fs 模块,但主进程(main.js )是可以的,这时候就需要使用进程通信。也就是说:要让 preload.js 通知 main.js,去调用 Node.js API 实现功能。

Electron 进程通信:

  • IPC:全称是 InterProcess Communication ,即:进程间通信。
  • IPC连接不同进程:在 Electron 应用中,主进程和渲染进程各自有不同的职责和运行环境。IPC是它们之间进行交互和协同工作的关键机制。没有有效的 IPC,主进程和渲染进程将无法有效地沟通和协调,导致应用功能受限。
  • 调用原生 API 的唯一途径:IPC 是 Electron 中最为核心的内容。IPC 是从 UI(通常在渲染进程中)调用原生 API 的唯一方法。这意味着如果想要在 Electron 应用中实现诸如文件系统操作、与操作系统交互等功能,必须通过 IPC 让主进程执行这些操作,然后将结果返回给渲染进程进行展示或进一步处理。
  • Electron 提供了 ipcMainipcRenderer 模块用于主进程和渲染进程之间的通信。
    • ipcMain(主进程中使用,从主进程到渲染进程的异步通信。)

      • 发送消息时,事件名称为channel ,即 通信通道
      • 回复同步信息时,需要设置event.returnValue
      • 可以使用event.reply(...)将异步消息发送回发送者。
    • ipcRenderer(渲染进程中使用,从渲染器进程到主进程的异步通信。)

模式1:渲染器进程到主进程(单向)

  • 概述:要将单向 IPC 消息从渲染器进程发送到主进程,需要在渲染器进程ipcRenderer.send 发送消息,在主进程中使⽤ ipcMain.on 接收消息。

  • 常用于:从 Web 内容调用主进程 API。

  • ipcRenderer.send(channel,...args)

    • 用于从渲染进程向主进程发送消息。
    • channel:字符串,表示消息的通道名称。主进程可以通过监听这个特定的通道名称来接收来自渲染进程的消息。例如:可以定义一个名为 'custom-action' 的通道。
    • ...args:这是一个可变参数,可以传递任意数量的参数。这些参数可以是任何有效的 JavaScript 值,如字符串、数字、对象等。
    • 用于单向通信的 ipcRenderer.send API 也可用于双向通信。在 Electron 7 之前,官方推荐使用 ipcRenderer.send 进行异步双向通信。在 Electron 7 中,官方添加 ipcRenderer.invoke API,用于处理渲染器进程中双向 IPC。
  • ipcMain.on(channel, listener)

    • 在主进程中监听来自渲染进程的特定通道消息。
    • hannel:这是一个字符串,表示特定的通信通道名称。渲染进程使用相同的通道名称通过 ipcRenderer.sendipcRenderer.invoke 向主进程发送消息。
    • listener:这是一个回调函数,当主进程接收到来自渲染进程通过指定通道发送的消息时,这个回调函数会被执行。
      • 回调函数通常接受两个参数:eventargsevent 代表事件对象,可用于回复渲染进程等操作;args 是渲染进程发送的参数,可以是单个值或一组值,具体取决于渲染进程的发送方式。

示例:

实现需求:点击按钮后,在⽤户的 D 盘创建⼀个 hello.txt ⽂件,⽂件内容来⾃于⽤户输⼊。

  1. 在页面中添加相关元素
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><metahttp-equiv="Content-Security-Policy"content="default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;"/><title>Electron</title><link rel="stylesheet" href="./index.css"></head><body><input id="content" type="text"><br><br><button id="btn">在⽤户的D盘创建⼀个hello.txt</button></body><script src="./render.js"></script>
</html>
  1. preload.js 中使⽤ ipcRenderer.send('信道', 参数) 发送消息,与主进程通信。
// contextBridge:在隔离的上下文中创建一个安全的、双向的、同步的桥梁。
// ipcRenderer是渲染进程中用于与主进程进行通信的模块。
const {contextBridge, ipcRenderer} = require('electron')// 把方法/数据暴露给渲染进程
contextBridge.exposeInMainWorld('customAPI', {saveFile: data => {// 渲染进程给主进程发送⼀个消息ipcRenderer.send('save-file', data)}
})
  1. render.js中,调用 preload.js 暴露的 saveFile 方法,通知主进程
const btn = document.getElementById('btn');
const content = document.getElementById('content');
btn.addEventListener('click', () => {// 在render.js 调用 preload.js 暴露出来的saveFile方法,通知主进程customAPI.saveFile(content.value);
});
  1. 主进程中,在加载页面之前,使用 ipcMain.on('信道', 回调) 配置对应回调函数,接收
    消息。
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path')
const fs = require('fs')
// 保存文件
function saveFile(event,data) {console.log(event, data)fs.writeFileSync('D:/hello.txt',data)// 通过 'response-save-file' 通道将结果回复给渲染进程。event.reply('response-save-file', '保存文件啦!');
}function createWindow() {const win = new BrowserWindow({width: 1000, // 窗口宽度height: 800, // 窗口高度webPreferences: {// 此处只能使用绝对路径preload: path.join(__dirname, 'preload.js')}});// 主进程注册对应回调ipcMain.on('save-file',saveFile)// 在窗口中加载一个远程页面win.loadFile('./pages/index.html');
}

渲染进程与主进程通信的流程

  1. 渲染进程触发:
    • 当渲染进程中的某个事件发生时,比如用户点击按钮或页面加载完成,可以调用 ipcRenderer.send('信道', 参数) 方法向主进程发送消息。
  2. 主进程接收和处理:
    • 主进程使用 ipcMain.on('信道', 回调) 方法监听特定的通道名称。当主进程接收到来自渲染进程的消息时,它可以根据通道名称和传递的参数执行相应的操作。
  3. 渲染进程接收回复:
    • 渲染进程可以使用 ipcRenderer.on 方法监听主进程的回复通道。当渲染进程接收到主进程的回复时,可以根据结果进行界面更新或其他处理。

模式2:渲染器进程到主进程(双向)

概述:渲染进程通过 ipcRenderer.invoke 发送消息,主进程使⽤ ipcMain.handle 接收并处理消
息。
常用于:从渲染器进程代码调用主进程模块并等待结果 。

  • ipcRenderer.invoke(channel, ...args)
    • channel:这是一个字符串,表示消息的通道名称。与ipcRenderer.send类似,主进程通过监听这个特定的通道名称来接收来自渲染进程的请求。
    • ...args:这是一个可变参数,可以传递任意数量的参数给主进程。这些参数可以是任何有效的 JavaScript 值,用于向主进程提供请求所需的信息。
    • ipcRender.invoke 的返回值是 Promise 实例。
  • ipcMain.handle(channel, listener)
    • channel:一个字符串,代表特定的通信通道名称。
    • listener:一个回调函数,当主进程接收到来自渲染进程通过指定通道发送的同步请求时,这个回调函数会被执行。
      • 回调函数通常接受两个参数:eventargsevent 代表事件对象,可用于回复渲染进程等操作;args 是渲染进程发送的参数,可以是单个值或一组值,具体取决于渲染进程的发送方式。
      • 回调函数需要返回一个值,这个值将作为响应发送回渲染进程。

示例:

实现需求:点击按钮从 D 盘读取 hello.txt 中的内容,并将结果呈现在页面上。

  1. 在页面中添加相关元素
<div id="content"></div>
<button id="btn">读取⽤户D盘的hello.txt</button
  1. preload.js 中使⽤ ipcRenderer.invoke('信道', 参数) 发送消息,与主进程通信。
// contextBridge:在隔离的上下文中创建一个安全的、双向的、同步的桥梁。
// ipcRenderer是渲染进程中用于与主进程进行通信的模块。
const {contextBridge, ipcRenderer} = require('electron')// 把方法/数据暴露给渲染进程
contextBridge.exposeInMainWorld('customAPI', {readFile: () => {// invoke 的返回值永远是Promisereturn ipcRenderer.invoke('read-file')}
})
  1. render.js中,调用 preload.js 暴露的 saveFile 方法,通知主进程
const btn = document.getElementById('btn');
const content = document.getElementById('content');
btn.addEventListener('click', async () => {let txt = await customAPI.readFile();content.innerHTML = txt
});
  1. 主进程中,在加载页面之前,使用 ipcMain.handle('信道', 回调) 配置对应回调函数,接收
    消息。
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path')
const fs = require('fs')
// 保存文件
function readFile(event,data) {return fs.readFileSync('D:/hello.txt').toString()
}function createWindow() {const win = new BrowserWindow({width: 1000, // 窗口宽度height: 800, // 窗口高度autoHideMenuBar: true, // 隐藏菜单栏webPreferences: {// 此处只能使用绝对路径preload: path.join(__dirname, 'preload.js')}});// 主进程注册对应回调ipcMain.handle('read-file', readFile)// 在窗口中加载一个远程页面win.loadFile('./pages/index.html');
}

ipcRenderer.invoke(channel, ...args)ipcRenderer.send(channel, ...args) 用于双向IPC的区别

  • ipcRenderer.send需要设置第二个 ipcRenderer.on 监听器来处理渲染器进程中的响应。 使用 ipcRenderer.invoke,直接获得作为 Promise 返回到原始 API 调用的响应值。
  • 没有显而易见的方法可以将 ipcRenderer.on('asynchronous-reply', (_event, arg) => {}) 消息与原始的 ipcRenderer.send('asynchronous-message') 消息配对。 如果不写备注,开发者可能也不知道asynchronous-replyasynchronous-message 通道的回复结果。如果通过这些通道非常频繁地来回传递消息,则需要添加其他应用代码来单独跟踪每个调用和响应。

模式3:主进程到渲染器进程

概述:主进程使用 win.webContents.send 发送消息,渲染进程使⽤ ipcRenderer.on 接收并处理消
息。
常用于:从主进程主动发送消息到渲染器进程。

示例:

需求:应⽤加载 6 秒钟后,主动给渲染进程发送⼀个消息

  1. 主进程中,使⽤ win.webContents.send('信道', 数据) 发送消息。
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');
function createWindow() {const win = new BrowserWindow({width: 1000, // 窗口宽度height: 800, // 窗口高度autoHideMenuBar: true, // 隐藏菜单栏webPreferences: {// 此处只能使用绝对路径preload: path.join(__dirname, 'preload.js')}});// 在窗口中加载一个远程页面win.loadFile('./pages/index.html');// 创建⼀个定时器setTimeout(() => {win.webContents.send('message', 'hello!');}, 6000);
}
  1. preload.js 中使⽤ ipcRenderer.on ('信道', 回调) 接收消息,并配置回调函数。
window.onload = () => {customAPI.getMessage(logMessage);
};
function logMessage(event, str) {console.log(event, str);
}

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

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

相关文章

【MySQL】子查询、合并查询、表的连接

目录 一、子查询 1、单行子查询 显示SMITH同一部门的员工信息 2、多行子查询 in关键字 查询和10号部门的工作岗位相同的雇员的名字、岗位、工资、部门号&#xff0c;但是筛选出的雇员的部门不能有10号部门 all关键字 查询工资比30号部门中所有雇员工资高的雇员的姓名、…

LLM端侧部署系列 | PowerInfer-2助力AI手机端侧部署47B大模型 (论文解读)

引言 简介 PowerInfer-2 概述 神经元感知的运行时推理 多态神经元引擎 内存中的神经元缓存 灵活的神经元加载 Neuron-Cluster-Level Pipeline 生成执行计划 执行 总结 0. 引言 一雨池塘水面平&#xff0c;淡磨明镜照檐楹。东风忽起垂杨舞&#xff0c;更作荷心万点声…

十、敌人锁定

方法&#xff1a;通过寻找最近的敌人&#xff0c;使玩家的面朝向始终朝向敌人&#xff0c;进行攻击 1、代码 在这个方法中使用的是局部变量&#xff0c;作为临时声明和引用 public void SetActorAttackRotation() {Enemys GameObject.FindGameObjectsWithTag("Enemy&qu…

工程机械车辆挖掘机自卸卡车轮式装载机检测数据集VOC+YOLO格式2644张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2644 标注数量(xml文件个数)&#xff1a;2644 标注数量(txt文件个数)&#xff1a;2644 标注…

Vue+NestJS项目实操(图书管理后台)

一、项目搭建 前端基于vben进行二次开发 在Github下载vben框架&#xff0c;搜索vben即可 下载地址&#xff1a;https://github.com/vbenjs/vue-vben-admin 下载完成后&#xff0c;进行安装依赖&#xff0c;使用命令&#xff1a; // 下载依赖 pnpm install// 运行项目 pnpm …

每日一练:地下城游戏

174. 地下城游戏 - 力扣&#xff08;LeetCode&#xff09; 题目要求&#xff1a; 恶魔们抓住了公主并将她关在了地下城 dungeon 的 右下角 。地下城是由 m x n 个房间组成的二维网格。我们英勇的骑士最初被安置在 左上角 的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔…

基于facefusion的换脸

FaceFusion是一个引人注目的开源项目&#xff0c;它专注于利用深度学习技术实现视频或图片中的面部替换。作为下一代换脸器和增强器&#xff0c;FaceFusion在人脸识别和合成技术方面取得了革命性的突破&#xff0c;为用户提供了前所未有的视觉体验。 安装 安装基础软件 安装…

数据链路层(以太网简介)

一.以太网数据帧结构&#xff1a; 目的地址&#xff0c;源地址&#xff0c;类型这三个被称为帧头&#xff0c;数据则被称为载荷&#xff0c;CRC则被称为帧尾&#xff08;校验和&#xff09; 二.数据帧结构分析 1.目的地址和源地址 i.地址解释 这两个地址指的是mac地址&#x…

国庆游玩计划安排

地点&#xff1a;上海前滩四方城 地点&#xff1a;船长酒吧 地点&#xff1a;上海&#x1f3db;️外滩华尔道夫

httpsok-v1.17.0-SSL通配符证书自动续签

&#x1f525;httpsok-v1.17.0-SSL通配符证书自动续签 介绍 httpsok 是一个便捷的 HTTPS 证书自动续签工具&#xff0c;基于全新的设计理念&#xff0c;专为 Nginx 、OpenResty 服务器设计。已服务众多中小企业&#xff0c;稳定、安全、可靠。 一行命令&#xff0c;一分钟轻…

HTML基础用法介绍一

VS code 如何快速生成HTML骨架注释是什么&#xff1f;为什么要写注释&#xff1f;注释的标签是什么&#xff1f;标题标签段落标签换行标签与水平线标签 (都是单标签&#xff09;文本格式化标签图片标签超链接标签音频标签视频标签 &#x1f698;正片开始 VS code 如何快速生成…

深度学习每周学习总结J1(ResNet-50算法实战与解析 - 鸟类识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 目录 0. 总结1. 设置GPU2. 导入数据及处理部分3. 划分数据集4. 模型构建部分5. 设置超参数&#xff1a;定义损失函数&#xff0c;学习率&a…

STM32+PWM+DMA驱动WS2812 —— 2024年9月24日

一、项目简介 采用STM32f103C8t6单片机&#xff0c;使用HAL库编写。项目中针对初学者驱动WS2812时会遇到的一些问题&#xff0c;给出了解决方案。 二、ws2812驱动原理 WS2812采用单线归零码的通讯方式&#xff0c;即利用高低电平的持续时间来确定0和1。这种通信方式优点是只需…

Vue 学习

vue 核心语法 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Vue 核心语法测试</title> </head><body&…

外包功能测试干了4年,技术退步太明显了。。。。。​

先说一下自己的情况&#xff0c;本科生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了差不多4年的功能测试&#xff0c;今年中秋&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测…

信号用wire类型还是reg类型定义

wire类型就是一根线&#xff0c;线有两端&#xff0c;一端发生改变&#xff0c;经过线传递的信号当然也会发生改变&#xff0c;reg类型则不同&#xff0c;可以把reg类型理解为存储数据的寄存器&#xff0c;当满足一定条件时&#xff0c;数值才被激活发生改变。 那么&#xff0…

【AI论文精读1】针对知识密集型NLP任务的检索增强生成(RAG原始论文)

目录 一、简介一句话简介作者、引用数、时间论文地址开源代码地址 二、摘要三、引言四、整体架构&#xff08;用一个例子来阐明&#xff09;场景例子&#xff1a;核心点&#xff1a; 五、方法 &#xff08;架构各部分详解&#xff09;5.1 模型1. RAG-Sequence Model2. RAG-Toke…

【Conda】修复 Anaconda 安装并保留虚拟环境的详细指南

目录 流程图示1. 下载 Anaconda 安装程序2. 重命名现有的 Anaconda 安装目录Windows 操作系统Linux 操作系统 3. 运行新的 Anaconda 安装程序Windows 操作系统Linux 操作系统 4. 同步原环境使用 robocopy 命令&#xff08;Windows&#xff09;使用 rsync 命令&#xff08;Linux…

C++11新特性(基础)【2】

目录 1.范围for循环 2.智能指针 3.STL中一些变化 4.右值引用和移动语义 4.1 左值引用和右值引用 4.2 左值引用与右值引用比较 4.3 右值引用使用场景和意义 4.4 右值引用引用左值及其一些更深入的使用场景分析 4.5 完美转发 1.范围for循环 int main() {int array[10] { 1,2,3,4…

超声波清洗机哪个品牌的最好?爆款超声波清洗机测评大揭秘

面对超声波清洗机的选购疑虑&#xff0c;许多朋友或是担心其效用不实&#xff0c;落入消费陷阱&#xff0c;或是已经遭遇了不尽如人意的产品体验。对此&#xff0c;我分享的经验或许能为你指点迷津&#xff01;基于亲测超过二十几款市面上热门的超声波眼镜清洗机&#xff0c;我…