electron-vite中的ipc通信

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通信,说谢谢

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WorkPlus内网通信软件的首选,助力企业实现高效内部沟通与协同

在企业内部&#xff0c;高效沟通是推动工作顺利进行的关键。而内网通信软件则成为了营造安全高效内部沟通环境的必要工具。作为一家领先的内网通信软件&#xff0c;WorkPlus以其卓越的性能和专业的功能&#xff0c;助力企业构建高效的内部沟通网络。 为什么选择WorkPlus作为内…

【Docker】部署和运行青龙面板:一个支持python3、javaScript、shell、typescript 的定时任务管理面板

引言 青龙面板是一个支持python3、javaScript、shell、typescript 的定时任务管理面板。 步骤 拉取镜像 从 Docker Hub 上拉取最新的 “qinglong” 镜像。 docker pull whyour/qinglong:latest启动容器 使用刚刚拉取的镜像来启动一个新的 Docker 容器。 docker run -dit \-v…

Java设计模式-前言

大家好&#xff0c;我是馆长&#xff01;从今天开始馆长开始对java设计模式进行讲解和整理分享给大家。馆长会尽快的整理完成设计模式的所有内容和讲解代码。从多方面进行模式的详细说明&#xff0c;方便各位看官理解和易学。 软件设计模式的概念 软件设计模式&#xff08;Sof…

Tensorflow2 GPU版本-极简安装方式

Tensorflow2 GPU版本-极简安装方式&#xff1a; 1、配置conda环境加速 https://wtl4it.blog.csdn.net/article/details/135723095https://wtl4it.blog.csdn.net/article/details/135723095 2、tensorflow-gpu安装 conda create -n STZZWANG_TF2 tensorflow-gpu2.0

11 - PXC集群|MySQL存储引擎

PXC集群&#xff5c;MySQL存储引擎 数据库系列文章PXC集群配置集群测试集群 MySQL存储引擎存储引擎介绍mysql服务体系结构mysql服务的工作过程处理查询访问的工作过程处理存储insert访问的工作过程 什么是搜索引擎 存储引擎管理查看存储引擎修改存储引擎 存储引擎特点myisam存储…

基于JavaWeb+SSM+Vue基于微信小程序的在线投稿系统的设计和实现

基于JavaWebSSMVue基于微信小程序的在线投稿系统的设计和实现 滑到文末获取源码Lun文目录前言主要技术系统设计功能截图 滑到文末获取源码 Lun文目录 目录 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计思想 1 2相关技术 2 2.1微信小程序 2 2.2 MYSQL数据库 3 2.3 u…

【Docker】安装Nginx容器并部署前后端分离项目

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Docker实战》。&#x1f3af;&#x1f3af; &…

使用vscode在wsl2中配置clangd环境

在vscode中安装这三个插件&#xff08;clangd需要科学上网或者从VSIX安装&#xff09; 之后创建一个空目录并进去。 使用快捷键ctrlshiftp&#xff0c;输入命令 Cmake:Quick Start 根据步骤选择。注意在创建CMakeLists.txt这一步选择跳过&#xff0c;直接输入enter&#xff0c…

【RHCE服务搭建实验】之DNS

目录 一、DNS简介二、安装DNS 一、DNS简介 域名系统&#xff08;DNS&#xff09;是一个分层的分布式数据库。它存储用于将Internet主机名映射到IP地址&#xff08;反之亦然&#xff09;的信息、邮件路由信息以及Internet应用程序使用的其他数据。 客户端通过调用解析器库在DNS…

R语言【cli】——builtin_theme():内置的CLI主题

Package cli version 3.6.0 Description 此主题始终处于活动状态&#xff0c;并且位于主题堆栈的底部。 Usage builtin_theme(dark getOption("cli.theme_dark", "auto")) Argument 参数【dark】&#xff1a;是否使用黑暗主题。cli.theme_dark选项可用…

实时语音克隆,准确复制音色:OpenVoice | 开源日报 No.150

myshell-ai/OpenVoice Stars: 9.6k License: NOASSERTION OpenVoice 是一个通过 MyShell 进行即时语音克隆的开源项目。 OpenVoice 可以准确地克隆参考音色&#xff0c;并生成多种语言和口音的语音。OpenVoice 允许对声音风格进行细粒度控制&#xff0c;如情感、口音以及节奏…

Pandas.Series.count() 非空单元格计数 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本&#xff1a; 本文基于 pandas2.1.2 编写。 关于本文内容更新&#xff1a; 随着pandas的stable版本更迭&#xff0c;本文持续更新&#xff0c;不断完善补充。 Pandas稳定版更新及变动内容整合专题&#xff1a; Pandas稳定版更新及变动迭持续更新。 Pandas API参…

R语言的ggplot2绘制分组折线图?

R绘制分组折线图.R 首先看数据情况&#xff1a;group有3组。Time有3组&#xff0c;数据意思是在3组3个时间点测量了某指标&#xff0c;现在要绘制组1、组2、组3某指标y按时间的变化趋势 数据情况&#xff1a; 看看最终的效果图如下&#xff1a; 下面是本次使用的代码 .libPat…

万界星空科技免费MES/开源MES/功能齐全,支持低代码大屏

目前国内智能制造如火如荼&#xff0c;工厂信息化、数字化是大趋势。如果找到一个工厂&#xff0c;搞定一个老板&#xff0c;搞软件的朋友就能吃几年。 开源软件不失为一条路子&#xff0c;大量的服务商选择开源MES做出了低成本的项目&#xff0c;收入也还可以。 今天介绍Git…

最新AI绘画创作系统ChatGPT网站程序源码V5.0版本搭建部署文档教程+Midjourney绘画动态全功能+MJ绘画局部编辑重绘

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

[小程序]样式与配置

一、外部样式导入 使用import加外部样式表的相对路径并以 ; 表示语句结束。 import "common.wxss"; 二、全局样式和局部样式 全局样式位于app.wxss中&#xff0c;会作用于整个项目中所有页面中。 局部样式位于对应的wxss文件中&#xff0c;仅作用于当前页面&#x…

0121-2-JavaScript高级程序设计1-10章

前言 通过阅读这本书写下的一些笔记 《JavaScript高级程序设计》 第1章——什么是JavaScript DOM将整个页面抽象为一组分层节点。 BOM用于支持访问和操作浏览器的窗口。 第2章——HTML中的JavaScript 2.1 < script >元素 元素描述async立即开始下载脚本&#xff0…

sshpass的安装与使用

一.简介 1.定义&#xff1a; ssh 登陆不能在命令行中指定密码&#xff0c;sshpass 的出现则解决了这一问题。它允许你用 -p 参数指定明文密码&#xff0c;然后直接登录远程服务器&#xff0c;它支持密码从命令行、文件、环境变量中读取。 2.使用 sshpass 原因 使用 sshpass…

【C++干货铺】C++11新特性——lambda表达式 | 包装器

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C干货铺 代码仓库&#xff1a;Gitee 目录 C98中的排序 lambda表达式 lambda表达式语法 表达式中的各部分说明 lambda表达式的使用 基本的使用 [var]值传递捕捉变量var ​编辑 [&var]引用传递捕…

pyspark笔记:over

1 方法介绍 在 PySpark 中&#xff0c;over 函数是一个非常重要的概念&#xff0c;尤其是在使用窗口函数&#xff08;例如 row_number, rank, dense_rank, lead, lag 等&#xff09;时。over 函数允许你对一个数据集进行分组&#xff0c;然后在每个分组内应用窗口函数。 1.1 …