天视通ipc地址修改工具_electron中的ipc通信(二)

本文详细介绍了Electron中主进程和渲染进程的通信方式,包括ipcMain和ipcRenderer模块的使用,同步和异步消息的发送与接收,以及事件监听与移除。此外,还提到了webworker在 Electron 中的潜在应用。
摘要由CSDN通过智能技术生成

主要参照electron中文官网,加上自己的一些理解,写的一个专题文章,如果觉得可以请点个赞或者关注一波,微信公众号:[猫十二的日常],欢迎留言和指出问题a

electron 通讯的方式

- 利用 `ipcMain` 和 `ipcRenderer` 模块
- 利用 electron.remote 模块

我们现在主要讲第一种通讯方式

理解主进程和渲染进程

主进程(Main Process)

  • 一个electron只能有一个主进程

  • 主进程指的是,你在执行 electron . 命令后,对应的当前目录下面的package.json文件下面的main的指定文件将会被执行,这里指的是

7b4d7e3aecdba201bf4b7dd61ee6bf96.png

  • 与创建GUI(类似创建窗口)相关的接口只能通过主进程来调用。

渲染进程(Renderer Process)

  • 由主进程调用GUI接口创建的页面,都有自己的进程,叫做渲染进程。主进程通过实例化BrowserWindow,每个BrowserWindow实例都会渲染一个web页面,相互独立,当一个BrowserWindow被销毁,相应的渲染进程也会被终止。

  • 渲染进程被主进程管理,每个渲染进程相互独立,只管理他们自己的web页面

两者需要通信,就需要用ipc通信

ipc通信的

在electron中我们需要主线程(Main Process)和渲染进程(Renderer Process)进行通信,需要用到两个模块

  • ipcMain

    从主进程到渲染进程的异步通信。ipcMain 是一个 EventEmitter 的实例。当在主进程中使用时,它处理从渲染器进程(网页)发送出来的异步和同步信息。从渲染器进程发送的消息将被发送到该模块。

  • ipcRenderer

    从渲染器进程到主进程的异步通信。ipcRenderer 是一个 EventEmitter 的实例。你可以使用它提供的一些方法从渲染进程 (web 页面) 发送同步或异步的消息到主进程。也可以接收主进程回复的消息。

ipc通讯的相关方法

渲染进程和主进程通讯的方法

目录准备,修改和删除都在这几个文件操作

my-electron-app/
├── package.json
├── main.js // 这个就是主进程
├── renderer.js // 这个就是渲染进程
└── index.html //web页面

index.html

<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>2020-01-08title>head><body>
Electron通讯演示<script src="./renderer.js">script> //外部引入jsbody>html>

main.js

const { app, BrowserWindow, ipcMain } = require("electron");
function createWindow() {
const win = new BrowserWindow({
width: 1920,
height: 1080,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
},
});
win.webContents.openDevTools(); //打开调试工具
win.loadFile("index.html");
}

app.whenReady().then(createWindow);

app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});

app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});

ipcMain.on("async-message", (event, arg) => {
//异步消息回复
console.log(`async-message:我接收到了异步消息`, arg);
event.reply("async-reply", "哥们我收到消息了-来自异步");
});

ipcMain.on("sync-message", (event, arg) => {
//同步消息回复
console.log(`async-message:我接收到了同步消息`, arg);
event.returnValue = "哥们我收到消息了-来自同步";
});

renderer.js

const { ipcRenderer } = require("electron");
// 同步消息
let message = ipcRenderer.sendSync("sync-message", "发个同步消息");
console.log("同步消息:", message);

//异步消息
ipcRenderer.on("async-reply", (event, arg) => {
console.log("异步消息:", arg);
});

ipcRenderer.send("async-message", "发个异步消息");

package.json

{
"name": "2020-01-08",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"electron": "^11.1.1"
}
}

结果

electron(主进程)

async-message:我接收到了同步消息 发个同步消息
async-message:我接收到了异步消息 发个异步消息

客户端(渲染进程)

同步消息: 哥们我收到消息了-来自同步
异步消息: 哥们我收到消息了-来自异步

本节会基于这几个文件进行修改和操作

对于以上的内容主要用到了几个方法实现了渲染进程向主进程通信

ipcMain.on(channel, listener) 主进程监听来自渲染进程的通信,ipcMain 是一个 EventEmitter 的实例

  • channel 监听的事件名称,String类型

  • listener 监听的回调函数 有两个入参

  • event IpcMainEvent ipc事件

    event 需要回复消息时有两种情况,一种是异步回复,一种是同步的回复

    • 回复同步信息时,需要设置event.returnValue

    • event.reply(...)将异步消息发送回发送者

    • 两者都在上面的demo体现

  • ...args any[] 后面的都是客户端传过来的入参

IpcMainEvent 继承之Event有下列属性值

  • processId(Integer类型) 发送此消息的渲染器进程的内部ID

  • frameId Integer类型)发送该消息的渲染进程框架的ID(可能是iframe)

  • returnValue (any类型)) 将其设置为要在同步消息中返回的值

  • reply (Function类型) 将 IPC 消息发送到渲染器框架的函数,该渲染器框架发送当前正在处理的原始消息。您应该使用“reply”方法回复发送的消息,以确保回复将转到正确的进程和框架。

  • channel String

  • ...args any[]

**ipcRenderer.sendSync(channel, …args) ** 渲染进程发送同步消息给主进程

  • channel 事件名称,String类型

  • …args any[]

返回 any - 由 ipcMain 处理程序发送过来的值。

发送同步消息将阻止渲染器的渲染过程,类似于async await 模式,最好还是选择异步版本的处理方式

ipcRenderer.send(channel, …args),渲染进程向主进程发送异步消息

  • channel 事件名称,String类型

  • …args any[]

以上的所有args参数,只能是被序列化的字符串,所有的函数、promise、Symbol、weakMaps、weakSets都会抛出异常,DOM结点在electron9也会抛出异常

其他的函数

只监听一次事件

ipcMain.once(channel, listener)

  • channel 监听的事件名称,String类型

  • listener 监听的回调函数 有两个入参

  • event IpcMainEvent ipc事件

    event 需要回复消息时有两种情况,一种是异步回复,一种是同步的回复

    • 回复同步信息时,需要设置event.returnValue

    • event.reply(...)将异步消息发送回发送者

    • 两者都在上面的demo体现

  • ...args any[] 后面的都是客户端传过来的入参

该事件函数只会监听一次,监听完将会被移除

用ipcMain.on监听

# main.js

// 正常的监听回复
ipcMain.on("on-message", (event, arg) => {
event.reply("on-reply-message", arg);
});

# renderer.js

for (let index = 0; index < 5; index++) {
ipcRenderer.send("on-message", `第${index}次`);
}

ipcRenderer.on("on-reply-message", (event, arg) => {
console.log(`回复:${arg}`);
});

//结果

回复:第0次
回复:第1次
回复:第2次
回复:第3次

用ipcMain.once监听

# main.js

ipcMain.once("one-message", (event, arg) => {
event.reply("one-reply-message", arg);
});

# renderer.js

for (let index = 0; index < 5; index++) {
ipcRenderer.send("one-message", `第${index}次`);
}

ipcRenderer.on("one-reply-message", (event, arg) => {
console.log(`回复:${arg}`);
});

//结果

回复:第0次

ipcRenderer.once(channel, listener)

  • 方法跟on事件监听差不多

该方法也是只监听主进程发的一次消息后,自动移除事件

# main.js

ipcMain.on("one-message", (event, arg) => {
event.reply("one-reply-message", arg);
});

# renderer.js

for (let index = 0; index < 5; index++) {
ipcRenderer.send("one-message", `第${index}次`);
}

ipcRenderer.once("one-reply-message", (event, arg) => {
console.log(`回复:${arg}`);
});

//结果

回复:第0次

移除监听事件

ipcMain.removeListener(channel, listener) 参数跟定义时的监听函数一致才能被移除

# main.js

function callback(event, arg) {
event.reply("reply", `主进程返回信息:${arg}`);
}
ipcMain.on("message", callback);
ipcMain.removeListener("message", callback);

# renderer.js

function watcher(event, arg) {
console.log(arg);
}
ipcRenderer.send("message", "渲染进程发信息");
ipcRenderer.on("reply", watcher);

//结果

ipcMain.removeAllListeners([channel])

  • channel可以移除这个事件的所有监听者

# main.js

function callback(event, arg) {
event.reply("reply", `主进程返回信息:${arg}`);
}
ipcMain.on("message", callback);
ipcMain.removeAllListeners("message");//指定的事件
//ipcMain.removeAllListeners(); //所有事件移除

# renderer.js

function watcher(event, arg) {
console.log(arg);
}
ipcRenderer.send("message", "渲染进程发信息");
ipcRenderer.on("reply", watcher);

//结果

异步的来回通信

这个主要的改变是类似返回promse来处理返回的结果,所以入参基本一致了

ipcMain.handle(channel, listener) 主进程的监听函数

ipcRenderer.invoke(channel, …args) 渲染进程的发送消息的函数

# main.js

ipcMain.handle("message", async (event, ...args) => {
let someMessage = await Promise.resolve("我是异步回来的消息");
return someMessage;
});

# renderer.js

(async () => {
let result = await ipcRenderer.invoke("message");
console.log(result);
})();

//结果
我是异步回来的消息

ipcMain.handleOnce(channel, listener) 单个执行一次

# main.js

ipcMain.handleOnce("message", async (event, ...args) => {
let someMessage = await Promise.resolve("我是异步回来的消息");
return someMessage;
});

# renderer.js

(async () => {
let result = await ipcRenderer.invoke("message");
console.log(result);
})();

//结果
我是异步回来的消息

ipcMain.removeHandler(channel)移除监听函数

# main.js

ipcMain.handle("message", async (event, ...args) => {
let someMessage = await Promise.resolve("我是异步回来的消息");
return someMessage;
});
ipcMain.removeHandler("message"); //一定要写移除那个事件名称
# renderer.js

(async () => {
let result = await ipcRenderer.invoke("message");
console.log(result);
})();

//结果
报错

使用webworker传递信息

**ipcRenderer.postMessage(channel, message, transfer])** 此函数类似于网页的中的 [webworker,百度没有查到其在electron的用法,自己按照webwork的方式写了一套 似乎是可以传递消息 (待更正)

# main.js

ipcMain.on("port", (e, msg) => {
const [port] = e.ports;
console.log(port, msg, e.ports);
port.postMessage("发信息给渲染进程");
});
# renderer.js
const { port1, port2 } = new MessageChannel();
ipcRenderer.postMessage("port", { message: "hello" }, [port2]);
port1.onmessage = (arg) => {
console.log(arg.data);
};
//结果
发信息给渲染进程

我们现在基本是讲了渲染进程主动向主进程发送消息并且得到回复,实际的情况,我们还有每个渲染进程互相通信,以及主进程主动向某个渲染进程通讯的操作 请听下回分解吧

如果觉得我的文章还可以,点个赞或者关注一下下,还有精彩的故事等着你哦,还可以云撸猫

8bdad972544c61cee989428685f1d74f.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值