electron-vite中的ipc通信

news2024/9/22 7:22:06

1. 概述

再electron中,进程间的通信通过ipcMain和ipcRenderer模块,这些通道是任意和双向的

1.1. 什么是上下文隔离进程

ipc通道是通过预加载脚本绑定到window对象的electron对象属性上的

2. 通信方式

2.1. ipcMain(也就是渲染进程向主进程的通信 单向)

  • 如果要将渲染器进程发送的主进程,我们使用ipcRenderer.send()在渲染进程中发送信息,然后在主进程中通过ipcMain.on来接收到渲染进程所发送的信息

2.2. 渲染器进程到主进程(双向)

  • 双向 IPC 的一个常见应用是从渲染器进程代码调用主进程模块并等待结果。 这可以通过将 ipcRenderer.invoke 与 ipcMain.handle 搭配使用来完成。

2.3. 主进程到渲染进程

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

3. 在electron-vite脚手架中进行统一使用

当用electron-vite脚手架搭建完项目之后在src文件夹下有三个文件夹

他们分别是:

  • main 主进程
  • preload 预加载脚本
  • renderer ui界面/渲染进程

3.1. ipcMain(也就是渲染进程向主进程的通信 单向)

  1. 首先在main.ts中新建ipc.ts文件来写入ipc通道和src目录在新建common(和main文件夹同级)来绑定ipc事件信息

//我们在这个中定义ipc的事件名称,翻遍后续的事件管理
export enum IpcEvents{
  SAYHELLO="sayhello"
}
//引入相关的事件名称
import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";


//ipc事件注册函数
const register=async ():Promise<void>=>{
  ipcMain.on(IpcEvents.SAYHELLO,async (e)=>{
    console.log('hello')
  })
	
}
export default {register}

最后一步我们需要再main/index.ts主进程文件中注册ipc通道事件

//首先引入我们的ipc文件
import ipc from './ipc'


//然后我们找到这个函数
app.whenReady().then(async () => {
  // Set app user model id for windows
	...
  ...
  await ipc.register()   //需要注意的是我们要在这儿createWindwo()函数之前注册ipc事件(也就是在创建窗口之前注册)
  createWindow()
	...
  ...

})

在渲染进程中使用

<template>
  <div class="home">
    <n-button @click="clickHandler">点击</n-button>
  </div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
//在此处点击事件
const clickHandler=()=>{
  window.electron.ipcRenderer.send(IpcEvents.SAYHELLO)   //此处调用事件
}
</script>
<style lang="scss" scoped>
.home{
  height: 100%;
  padding: 16px;
}
</style>

当我们点击后发现控制台出现相应的打印输出后表示注册成功

3.1.1. 如何进行传参

  • 我们在ipc通道中进行参数/数据传递的时候,建议使用JSON序列化
<template>
  <div class="home">
    <n-button @click="clickHandler">点击</n-button>
  </div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
const datalist=[
  {name:"yu",age:23,sex:"男"},
  {name:"chao",age:23,sex:"女"},
  {name:"zhi",age:23,sex:"未知"},
  {name:"wang",age:24,sex:"男"},
]
const clickHandler=()=>{
  const data=JSON.stringify(datalist)
  window.electron.ipcRenderer.send(IpcEvents.SAYHELLO,data)
}
</script>
<style lang="scss" scoped>
.home{
  height: 100%;
  padding: 16px;
}
</style>
import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";

const register=async ():Promise<void>=>{
  ipcMain.on(IpcEvents.SAYHELLO,async (e,data)=>{
    const dataList=JSON.parse(data)
    console.log(dataList)
  })
}

export default {register}

点击后会发现在控制台中中文会乱码

electron中中文乱码解决方案

在启动命令之前添加chcp 65001解决electron控制台下打印中文乱码

    "dev": "chcp 65001 && electron-vite dev",

 

现在我们重新启动项目,可以清除的看到中文不会乱码

3.2. 主进程向渲染进程通信

我们首先在src/renderer/src下新建文件夹名hook

然后新建文件useIpcRendererOn.ts

import { onUnmounted } from 'vue'

//这儿要注意引入的ipc事件的地址,然后无脑粘贴
import { IpcEvents } from '../../../common/ipcEvents'

type IpcRendererListener = (event: any, ...args: any[]) => void


//用于监听主进程向渲染进行双向的通信
export default function useIpcRendererOn(
  channel: IpcEvents,
  listener: IpcRendererListener
): any {
  const ipc = (window as any).electron.ipcRenderer

  onUnmounted(() => {
    ipc.removeListener(channel, listener)
  })

  return (window as any).electron.ipcRenderer.on(channel, listener)
}

重新定义新的事件名称

//我们在这个中定义ipc的事件名称,翻遍后续的事件管理
export enum IpcEvents{
  SAYHELLO="sayhello",
  SAYWORLD="sayworld"
}

住进程向渲染进程发送消息

import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";

const register=async ():Promise<void>=>{
  ipcMain.on(IpcEvents.SAYHELLO,async (e,data)=>{
    const dataList=JSON.parse(data)
    console.log(dataList)
    const world=JSON.stringify([
      {
        name:"这个是主进程传递过来的",
        value:1
      }
    ])
    //在这儿向渲染进程发送信息
    e.sender.send(IpcEvents.SAYWORLD,world)
  })
}

export default {register}

我们在渲染进程中来监听主程序的发送的数据

<template>
  <div class="home">
    <n-button @click="clickHandler">点击</n-button>
  </div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
import useIpcRendererOn from "../../../hook/useIpcRendererOn";
const datalist=[
  {name:"yu",age:23,sex:"男"},
  {name:"chao",age:23,sex:"女"},
  {name:"zhi",age:23,sex:"未知"},
  {name:"wang",age:24,sex:"男"},
]
const clickHandler=()=>{
  const data=JSON.stringify(datalist)
  window.electron.ipcRenderer.send(IpcEvents.SAYHELLO,data)
}
//用来监听渲染进程发送的信息
useIpcRendererOn(IpcEvents.SAYWORLD,async (_,data)=>{
  const list=JSON.parse(data)
  console.log(list)
})
</script>
<style lang="scss" scoped>
.home{
  height: 100%;
  padding: 16px;
}
</style>

当我们点击按钮后回清晰看到在页面的开发者工具中打印出来主进程中传递过来的数据

上述行为整体剖析

  • 我们首先通过在页面中进行点击来触发window.electron.ipcRenderer.send(IpcEvents.SAYHELLO,data)中的SAYHELLO事件
  • 然后在住进程中通过 ipcMain.on(IpcEvents.SAYHELLO)接收到相对应的点击事件并打印(打印在控制台)
  • 然后再通过e.sender.send(IpcEvents.SAYWORLD)向渲染进程发送信息
  • 渲染进程通过useIpcRendererOn(IpcEvents.SAYWORLD),来监听SAYWORLD主进程发送的事件

由以上四步在住进程中形成了统一的闭环操作。

以上情况几乎能够完成所有的ipc通信操作,还有一种情况后续再说

3.3. 择日不如撞日(最后一种方式)双向奔赴

首先在ipcEvents.ts中注册一个事件名称

export enum IpcEvents{
  SAYHELLO="sayhello",
  SAYWORLD="sayworld",
  SAYTHANKYOU='Thankyou'
}

我们首先在渲染界面发送消息

<template>
  <div class="home">
    <n-button @click="clickHandler">点击</n-button>
    <n-button @click="sayTankyouHandler">说谢谢</n-button>
  </div>
</template>
<script lang="ts" setup>
import {IpcEvents} from "../../../../../common/ipcEvents";
import useIpcRendererOn from "../../../hook/useIpcRendererOn";
const datalist=[
  {name:"yu",age:23,sex:"男"},
  {name:"chao",age:23,sex:"女"},
  {name:"zhi",age:23,sex:"未知"},
  {name:"wang",age:24,sex:"男"},
]
const clickHandler=()=>{
  const data=JSON.stringify(datalist)
  window.electron.ipcRenderer.send(IpcEvents.SAYHELLO,data)
}
useIpcRendererOn(IpcEvents.SAYWORLD,async (_,data)=>{
  const list=JSON.parse(data)
  console.log(list)
})
const sayTankyouHandler=async ()=>{
  //这儿发送消息,向主进程
  await window.electron.ipcRenderer.invoke(IpcEvents.SAYTHANKYOU).then((data: string) => {
    //data便是渲染进程中然会过来的数据
    console.log(data)
  })
}
</script>
<style lang="scss" scoped>
.home{
  height: 100%;
  padding: 16px;
}
</style>

住进程中接收并返回

import {ipcMain} from 'electron'
import {IpcEvents} from "../common/ipcEvents";

const register=async ():Promise<void>=>{
  ipcMain.on(IpcEvents.EVPLAY,async (e,data)=>{
    const dataList=JSON.parse(data)
    console.log(dataList)
    const world=JSON.stringify([
      {
        name:"这个是主进程传递过来的",
        value:1
      }
    ])
    e.sender.send(IpcEvents.SAYWORLD,world)
  })
  //这个便是进行的双向通信说谢谢
  ipcMain.handle(IpcEvents.SAYTHANKYOU,()=>{
    return '谢谢'
  })
}

export default {register}

我们可以看见非常的有礼貌,那你呢?

值得注意的是:

  • 以上操作我们都是在electron-vite的脚手架下完成的,electron-vite已经完成了文件预加载的任务(也就是说已经把electron的对象绑定到了window对象上)
  • 如果您自己搭建electron那么需要自己创建预加载文件。
  • 还有另外一种情况就是,我们此预加载文件是在主窗口下引入,如果新打开窗口不是主窗口那么需要在新打开窗口中重新引入预加载文件,否则Ipc通信不可使用

为了解决红色方框的第三个问题,以示诚意贴张图片

以上便是完整的ipc通信,说谢谢

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

福昕软件的使用

快捷操作 快捷键 快捷键功能备注Ctrl P打印 Ctrl W关闭 Ctrl B书签 鼠标放菜单栏&#xff0c;单击右键即可导入/导出 自定义菜单栏文件-->偏好设置-->文档 1、多实例&#xff1a;单击PDF后均重新打开一个新界面。

数字图像处理期末速成笔记

目录 一、基础知识二、相邻像素间基本关系三、图像增强方法1、直方图求解2、直方图均衡化3、直方图规定化4、图像平滑5、邻域平均法&#xff08;线性&#xff09;6、 中值滤波法&#xff08;分线性&#xff09;7、中值滤波与领域平均的异同8、4-邻域平滑法9、超限像素平滑法10、…

C++ BuilderXE关于FDQuery组件记录限制设定

这样修改就可以查询返回所有记录。 TFDQuery.RecordCount,或TDateSet.RecordCount只显示了可见的50条数据&#xff0c;但实际上数据的总量超过了这个数量。为了解决这个问题&#xff0c;我们可以通过更改TFDConection.FetchOptions.RecordCountMode属性为fmTotal&#xff0c;以…

多维时序 | Matlab实现CNN-BiLSTM-Mutilhead-Attention卷积双向长短期记忆神经网络融合多头注意力机制多变量时间序列预测

多维时序 | Matlab实现CNN-BiLSTM-Mutilhead-Attention卷积双向长短期记忆神经网络融合多头注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现CNN-BiLSTM-Mutilhead-Attention卷积双向长短期记忆神经网络融合多头注意力机制多变量时间序列预测效果一览基本介绍程序设计…

Elasticsearch 入门向使用

文章目录 ElasticSearch简介倒排索引安装(单节点)分词器kibana与Mysql概念上的对比索引库CRUD文档CRUDDSL查询相关性算分Function Score Query自定义算分Boolean Query 搜索结果处理排序分页高亮 数据聚合 aggregations自动补全数据同步集群 ElasticSearch 简介 Elasticsearc…

java SSM园林绿化管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM园林绿化管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

【论文阅读】GPT4Graph: Can Large Language Models Understand Graph Structured Data?

文章目录 0、基本介绍1、研究动机2、准备2.1、图挖掘任务2.2、图描述语言&#xff08;GDL&#xff09; 3、使用LLM进行图理解流程3.1、手动提示3.2、自提示 4、图理解基准4.1、结构理解任务4.1、语义理解任务 5、数据搜集5.1、结构理解任务5.2、语义理解任务 6、实验6.1、实验设…

Spark面试题

1. spark core 1.简述hadoop 和 spark的不同点&#xff08;为什么spark更快&#xff09;♥♥♥ shuffle都是需要落盘的&#xff0c;因为在宽依赖中需要将上一个阶段的所有分区数据都准备好&#xff0c;才能进入下一个阶段&#xff0c;那么如果一直将数据放在内存中&#xff0c…

ARM多核调度器DSU

1. 背景 从A75开始&#xff0c;ARM提出了一个新的多核心管理系统单元&#xff0c;叫做DSU(DynamIQ Shared Unit)。DSU的核心功能是控制CPU内核&#xff0c;使其成簇Cluster使用&#xff0c;簇内每一个核心可以单独开关、调整频率/电压&#xff0c;能效表现更佳&#xff0c;甚至…

手动正则删除console.log

依赖删除的可以先出去了 先得删除箭头函数里的 正则匹配不能直接删&#xff0c;如这种箭头函数&#xff0c;得先全局改了 然后正则 console.log(.*?) 选中》空着〉全局替换 最后删除 // 因为有的 console.log在代码块原来就是被空着状态&#xff0c; 所以也得全局为空替…

正则表达式..

1.字符串的合法检验 现在有一个字符串验证码 我们需要检验其的合法性 什么条件才能够使得字符串合法呢&#xff1f;就是6-10个字符串长度 并且以字母开头 并且其中由字母、数字、下划线构成 那么我们可以先通过自定义的方式进行检验 public class Main {public static void m…

通过Konva.js实现canvas列表滚动

列表可以通过Konva.js中的Rect来实现&#xff0c;通过group可以丰富列表的内容 在滚动方面&#xff0c;可以通过vue的scroll方法&#xff0c;通过rect中的move方法来修改y值即可 我这里设置的是一个透明的盒子在想要滚动的canvas上&#xff0c;这样就可以实现直接滚动canvas列…

K8s(七)四层代理Service

Service概述 Service在Kubernetes中提供了一种抽象的方式来公开应用程序的网络访问&#xff0c;并提供了负载均衡和服务发现等功能&#xff0c;使得应用程序在集群内外都能够可靠地进行访问。 每个Service都会自动关联一个对应的Endpoint。当创建一个Service时&#xff0c;Ku…

springboot109新闻稿件管理系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的新闻稿件管理系统 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获…

SpringMVC下半篇之整合ssm

4.ssm整合 4.1.创建表 CREATE TABLE account (id int(11) NOT NULL AUTO_INCREMENT,name varchar(20) DEFAULT NULL,money double DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8;4.2.创建工程 4.3.pom.xml <?xml version"1.0" encoding&…

【图形学】颜色线性插值和Wu反走样算法

颜色线性插值 绘制一条颜色渐变的直线&#xff0c;直线上每一个点的颜色都来自端点颜色的线性插值。线性插值公式为 P ( 1 − t ) P s t a r t t P e n d P 是直线上任意一个点&#xff0c; P s t a r t 是直线的起点&#xff0c; P e n d 是直线的终点 对应直线上任意一点…

[flutter]GIF速度极快问题的两种解决方法

原因&#xff1a; 当GIF图没有设置播放间隔时间时&#xff0c;电脑上会默认间隔0.1s&#xff0c;而flutter默认0s。 解决方法一&#xff1a; 将图片改为webp格式。 解决方法二&#xff1a; 为图片设置帧频率&#xff0c;添加播放间隔。例如可以使用GIF依赖组件设置每秒运行…

低代码技术杂谈

一、探讨低代码的定义 “Low-Code”是什么&#xff1f;身为技术人员听到这种技术名词&#xff0c;咱们第一反应就是翻看维基百科 或者其他相关技术论文&#xff0c;咱们想看维基百科的英文介绍&#xff1a; A low-code development platform (LCDP) provides a development env…

Docker(七)使用网络

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker 中的网络功能介绍 Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。 一、外部访问容器 容器中可以运行一些网络应用&…

数学建模常见算法的通俗理解(1)

目录 1.层次分析法&#xff08;结合某些属性及个人倾向&#xff0c;做出某种决定&#xff09; 1.1 粗浅理解 1.2 算法过程 1.2.1 构造判断矩阵 1.2.2 计算权重向量 1.2.3 计算最大特征根 1.2.4 计算C.I.值 1.2.5 求解C.R.值 1.2.6 判断一致性 1.2.7 计算总得分 2 神经…