electron进程间通讯(IPC模块通讯)

上一篇 electron主进程和渲染进程
下一篇 electron API

目标: 掌握进程间通讯

进程间通讯的常见情况

  • 通知事件: 例如渲染进程通知主进程创建一个提醒
  • 数据传输: 例如某个页面需要获得当前的内存数据,需要主进程进行数据传输
  • 共享数据: 例如公共的用户信息共享

IPC模块通讯

  • electron 提供了IPC通讯模块, 即主进程的 pcMain 和渲染进行的 ipcRenderer 进行通讯
  • ipcMainipcRenderer 都是Eventmitter对象
进程通讯实例(渲 => 主)
  • Callback 写法
    ipcRenderer.send(channel, ...args)
    ipcMain.on(channel, handler)
// 渲染进程 ipc.js
const { ipcRenderer } = require('electron');
window.onload = function () {
  // 渲染进程发出事件 channel, 参数 1,2,3
  ipcRenderer.send("channel1", 1, 2, 3);
}

// 主进程 main.js
const { app, BrowserWindow, ipcMain } = require('electron');
let win = null;
app.on("ready", () => {
  win = new BrowserWindow({
    width: 800,
    height: 500,
    webPreferences: { nodeIntegration: true }
  })
  win.loadFile("index.html");

  // 主进程监听事件
  ipcMain.on("channel1", (e, a, b, c) => {
    // 乱码, 在package.json中添加 "start": "chcp 65001 && electron ."
    console.log("监听到渲染进程的发出的事件(callback)", a, b, c);
  })

  win.on("close", () => {
    win = null;
  })
})

//***********************************************************************************
注意点:  
如果控制台输出中文乱码,可以在package.json中添加 "start": "chcp 65001 && electron ."
使用 npm start 启动项目
//***********************************************************************************
结果
  • Promise 写法(Electron 7.0 之后, 处理请求 + 响应模式)
    ipcRenderer.invoke(channel, ...args)
    ipcMain.handle(channel, handler)
// 渲染进程 ipc.js
// 发出事件
ipcRenderer.invoke("channel2", 1, 2, 3);

// 主进程 main.js
ipcMain.handle("channel2", (e, a, b, c) => {
    console.log("监听到渲染进程的发出的事件(Promise)", a, b, c)
})
结果
进程通讯实例(主 => 渲)

ipcRenderer.on(channel, handler) (渲)
webContents.send(channel) (主)

ipcRenderer.on("channel3", () => {
    alert("渲染进程接收到主进程事件");
  })

// 主进程向渲染进程通讯
  setTimeout(() => {
    win.webContents.send("channel3");
  }, 1000)
END
进程通讯实例(页面间通讯)
  • 通知事件
    electron 5 之前: 通过主进程转发(即:渲 => 主 => 渲)
    electron 5 之后: ipcRenderer.sendTo
// 主进程 main.js
const { app, BrowserWindow, ipcMain } = require('electron');
let win1 = null;
let win2 = null;
app.on("ready", () => {
  win1 = new BrowserWindow({
    width: 800,
    height: 500,
    webPreferences: {
      nodeIntegration: true,
      enableRemoteModule: true
    }
  })

  win2 = new BrowserWindow({
    width: 800,
    height: 500,
    webPreferences: {
      nodeIntegration: true,
      enableRemoteModule: true
    }
  })

  // 保存win2窗口的 id
  global.sharedObject = {
    win2WebContentsId: win2.webContents.id
  }

  win2.loadFile("page2.html");
  win1.loadFile("page1.html");

  win1.on("close", () => { win1 = null;})
  win2.on("close", () => {win2 = null;})
})
---- --- ---- --- --- ---- -- --- - -- - - -- - - ---- --- -- -- - - -- - - -- - - 


// page1页面js
const { ipcRenderer, remote } = require('electron');
// 获取page2页面的 id
let { win2WebContentsId } = remote.getGlobal("sharedObject");
// 根据页面 id 发送事件
ipcRenderer.sendTo(win2WebContentsId, "page1Event", 1, 2, 3);
---- --- ---- --- --- ---- -- --- - -- - - -- - - ---- --- -- -- - - -- - - -- - - 


// page2页面
const { ipcRenderer } = require('electron');
ipcRenderer.on("page1Event", (e, a, b, c) => {
  alert("我是page2, 监听到 page1Event", a, b, c);
})



******************************************************************
注意点:
electron 10下,remote默认关闭,需要手动开启
enableRemoteModule: true,   // 打开remote模块
******************************************************************
结果
  • 数据共享
    Web技术(localStorage、sessionStorage、indexedDB)
    使用remote(不推荐)
END

你可能感兴趣的:(electron进程间通讯(IPC模块通讯))