Electron 中渲染进程与渲染进程之间的通信详解

Electron中渲染进程与渲染进程之间的通信主要有两种方式,一种是通过本地存储来实现,另外一种就是借助主进程进行传递消息。

1. 渲染进程之间通过本地存储进行通信

渲染进程index传递消息。

// index.js
window.onload = () => {
    var button = document.getElementById("button");
    button.onclick=()=>{
        // 渲染进程index与渲染进程news之间直接进行通信
        localStorage.setItem("msg","世界那么大,我想去看看");
    };
};

渲染进程news获取消息。

// news.js
window.onload=()=>{
    // 渲染进程index与渲染进程news之间直接进行通信
    var msg = localStorage.getItem("msg");
    alert(msg);
    // 世界那么大,我想去看看
}

 

2. 当前渲染进程向新打开的渲染进程传递消息

渲染进程index发送消息。

// index.js
const {ipcRenderer} =require("electron");
window.onload = () => {
    var button = document.getElementById("button");
    button.onclick=()=>{
        // 发送消息
        ipcRenderer.send(
            "openNews",
            "钱包那么少,哪儿也去不了"
        );
    };
};

主进程ipcMain接受渲染进程index的消息,并传递给新创建的渲染进程news。

// ipcMain.js
const {BrowserWindow,ipcMain} = require("electron");
const path = require("path");
// 监听渲染进程index传递的消息并创建新的渲染进程news
ipcMain.on("openNews",(e,data)=>{
    
    const newsWindow = new BrowserWindow({
        width:400,
        height:300,
        webPreferences:{
            // 集成node
            nodeIntegration:true,
            // 取消上下文隔离
            contextIsolation:false,
            // 启用remote模块
            enableRemoteModule:true
        }
    });
    newsWindow.loadFile(path.join(__dirname,"../news.html"));

    // 监听渲染进程news加载完成
    newsWindow.webContents.on('did-finish-load',(event)=>{
        // 发送消息给渲染进程news
        newsWindow.webContents.send("toNews",data)
    });
});

渲染进程news接受渲染进程index通过主进程ipcMian传递过来的消息。

// new.js
const {ipcRenderer} = require("electron");
// 监听渲染进程index通过主进程ipcMain发送的消息
ipcRenderer.on("toNews",(e,data)=>{
    alert(data);
    // 钱包那么少,哪儿也去不了
});

 

3. 新打开的渲染进程向之前已经打开的渲染进程传递消息

渲染进程news发送消息。

// news.js
window.onload = ()=>{
    var button = document.getElementById("button");
    button.onclick = ()=>{
        // 渲染进程news向渲染进程index传递消息
        ipcRenderer.send("sendToIndex","工作没做完,还得继续干")
    };
}

主进程ipcMain接受渲染进程news的消息,并传递给之前已经打开的渲染进程index。

// ipcMain.js
const {BrowserWindow,ipcMain} = require("electron");
const path = require("path");
// 保存已经打开的渲染进程index
var indexId;

// 监听渲染进程index传递的消息并创建新的渲染进程news
ipcMain.on("openNews",(e,data)=>{

    // 创建渲染进程news之前获取当前渲染进程index的id并保存;
    indexId = BrowserWindow.getFocusedWindow().id;

    // 创建渲染进程news
    ......

});


// 监听渲染进程news中传递过来的消息
ipcMain.on("sendToIndex",(e,data)=>{
    // console.log(data);
    // 工作没做完,还得继续干

    // 获取之前保存的渲染进程index
    var mainWindow = BrowserWindow.fromId(indexId);
    // 发送消息给渲染进程index
    mainWindow.webContents.send("toIndex",data);

})

渲染进程index监听渲染进程news通过主进程ipcMian传递过来的消息。

// index.js
const {ipcRenderer} =require("electron");

// 监听渲染进程news通过主进程ipcMain传过来的消息
ipcRenderer.on("toIndex",(e,data)=>{
    console.log(data);
});

 

4. 代码实例

主进程main.js文件代码:

// main.js
const { app, BrowserWindow } = require("electron");
const path = require("path");


const createWindow = () => {
    // 创建窗口
    const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            // 开启node
            nodeIntegration: true,
            // 取消上下文隔离
            contextIsolation: false,
            // 开启remote
            enableRemoteModule:true,
        }
    });
    // 加载本地文件
    mainWindow.loadFile(path.join(__dirname, "index.html"));
    // 加载远程地址
    // mainWindow.loadURL('https://github.com');

    // 开启调试模式
    mainWindow.webContents.openDevTools();

    // 引入主进程的通信
    require('./ipcMain/ipcMain.js');

}

// 监听应用的启动事件
app.on("ready", createWindow);

// 兼容MacOS系统的窗口关闭功能
app.on("window-all-closed", () => {
    // 非MacOS直接退出
    if (process.platform != "darwin") {
        app.quit();
    }
});

// 点击MacOS底部菜单时重新启动窗口
app.on("activate", () => {
    if (BrowserWindow.getAllWindows.length == 0) {
        createWindow();
    }
})

主进程main.js中引入的ipcMain.js文件代码:

// ipcMain.js
const {BrowserWindow,ipcMain} = require("electron");
const path = require("path");
// 保存已经打开的渲染进程index
var indexId;

// 监听渲染进程index传递的消息并创建新的渲染进程news
ipcMain.on("openNews",(e,data)=>{

    // 创建渲染进程news之前获取当前渲染进程index的id并保存;
    indexId = BrowserWindow.getFocusedWindow().id;

    const newsWindow = new BrowserWindow({
        width:400,
        height:300,
        webPreferences:{
            // 集成node
            nodeIntegration:true,
            // 取消上下文隔离
            contextIsolation:false,
            // 启用remote模块
            enableRemoteModule:true
        }
    });

    newsWindow.loadFile(path.join(__dirname,"../news.html"));

    // 监听渲染进程news加载完成
    newsWindow.webContents.on('did-finish-load',(event)=>{
        // 发送消息给渲染进程news
        newsWindow.webContents.send("toNews",data)
    });

});


// 监听渲染进程news中传递过来的消息
ipcMain.on("sendToIndex",(e,data)=>{
    // console.log(data);
    // 工作没做完,还得继续干

    // 获取之前保存的渲染进程index
    var mainWindow = BrowserWindow.fromId(indexId);
    // 发送消息给渲染进程index
    mainWindow.webContents.send("toIndex",data);

})

渲染进程index.html文件代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Electron开发</title>
</head>
<body>
    <p>Electron中渲染进程与渲染进程之间的通信</p>
    <br><br>
    <button id="button">打开新窗口</button>
    <script src="./ipcRenderer/index.js"></script>
</body>


</html>

渲染进程index.html中引入的index.js文件代码:

// index.js
const {ipcRenderer} =require("electron");
window.onload = () => {
    var button = document.getElementById("button");
    button.onclick=()=>{

        // 渲染进程index与渲染进程news之间直接进行通信
        // localStorage.setItem("msg","世界那么大,我想去看看");
        
        // 发送消息
        ipcRenderer.send(
            "openNews",
            "钱包那么少,哪儿也去不了"
        );
    };
};

// 监听渲染进程news通过主进程ipcMain传过来的消息
ipcRenderer.on("toIndex",(e,data)=>{
    console.log(data);
});

渲染进程news.html文件代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Electron开发</title>
</head>
<body>

    <p>这是打开的新页面</p>
    <button id="button">执行index里面的方法并传值</button>
    <script src="./ipcRenderer/news.js"></script>
</body>

</html>

渲染进程news.html中引入的news.js文件代码:


const {ipcRenderer} = require("electron");

// window.onload=()=>{
    // 渲染进程index与渲染进程news之间直接进行通信
    // var msg = localStorage.getItem("msg");
    // alert(msg);
    // 世界那么大,我想去看看
// }

// 监听渲染进程index通过主进程ipcMain发送的消息
ipcRenderer.on("toNews",(e,data)=>{
    alert(data);
    // 钱包那么少,哪儿也去不了
});



window.onload = ()=>{
    var button = document.getElementById("button");
    button.onclick = ()=>{
        // 渲染进程news向渲染进程index传递消息
        ipcRenderer.send("sendToIndex","工作没做完,还得继续干")
    };
}


 

上一篇:electron +vue自定义点击最大化、最小化和关闭窗口事件功能


下一篇:亚马逊解决Echo回音问题 下调二代Echo Dot售价