跳转到主内容

ipcRenderer

从渲染器进程到主进程的异步通信。

进程: Renderer

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

请参阅 进程间通信(IPC)教程 获取代码示例。

方法

ipcRenderer 模块使用以下方法来监听事件和发送消息。

ipcRenderer.on(channel, listener)

监听 channel, 当新消息到达,将通过 listener(event, args...) 调用 listener。

ipcRenderer.off(channel, listener)

Alias for ipcRenderer.removeListener.

ipcRenderer.once(channel, listener)

添加一次性 listener 函数。 这个 listener 只会在 channel下一次收到消息的时候被调用,之后这个监听器会被移除。

ipcRenderer.addListener(channel, listener)

Alias for ipcRenderer.on.

ipcRenderer.removeListener(channel, listener)

为特定的 channel 从监听队列中删除特定的 listener 监听者.

ipcRenderer.removeAllListeners(channel)

  • channel string

移除所有的监听器,当指定 channel 时只移除与其相关的所有监听器。

ipcRenderer.send(channel, ...args)

  • channel string
  • ...args any[]

通过channel向主进程发送异步消息,可以发送任意参数。 参数将使用 Structured Clone Algorithm进行序列化,就像 window.postMessage,因此原型链将不会包含在内。 发送 Functions, Promises, Symbols, WeakMaps, 或 WeakSets 将抛出异常

注意: 发送非标准的 JavaScript 类型,如DOM 对象或特殊Electron 对象将会抛出异常。

主线程不支持 DOM 对象比如 ImageBitmap, File, DOMMatrix 等对象, 它们无法通过Electron的IPC发送到主线程,主要原因是主线程无法对他们进行解码 若尝试通过IPC发送这种对象数据将返回异常

主进程中,通过监听 ipcMain 模块下的 channel 来处理这些消息

如果需要将一个 MessagePort 传输到主进程,请使用 ipcRenderer.postMessage

如果你想从主进程中收到单个响应,比如一个方法调用的结果, 请考虑使用 ipcRenderer.invoke

ipcRenderer.invoke(channel, ...args)

  • channel string
  • ...args any[]

Returns Promise<any> - Resolves 主进程返回值

通过 channel 向主过程发送消息,并异步等待结果。 参数将使用 Structured Clone Algorithm进行序列化,就像 window.postMessage,因此原型链将不会包含在内。 发送 Functions, Promises, Symbols, WeakMaps, 或 WeakSets 将抛出异常

主进程应该使用 ipcMain.handle() 监听 channel

例如:

// 渲染进程
ipcRenderer.invoke('some-name', someArgument).then((result) => {
// ...
})

// 主进程
ipcMain.handle('some-name', async (event, someArgument) => {
const result = await doSomeWork(someArgument)
return result
})

如果需要将一个 MessagePort 传输到主进程,请使用 ipcRenderer.postMessage

如果你不需要回复此消息,请考虑使用 ipcRender.send

注意: 发送非标准的 JavaScript 类型,如 DOM 对象或特殊 Electron 对象将会抛出异常。

主线程不支持 DOM 对象比如 ImageBitmap, File, DOMMatrix 等对象, 它们无法通过Electron的IPC发送到主线程,主要原因是主线程无法对他们进行解码 若尝试通过IPC发送这种对象数据将返回异常

请注意 如果主进程中的处理程序出现错误, 由 invoke 返回的 promise 将被 reject。 然而,渲染器进程中的 Error 对象 将与主进程中的对象不同。

ipcRenderer.sendSync(channel, ...args)

  • channel string
  • ...args any[]

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

通过 channel 向主过程发送消息,并同步等待结果。 参数将使用 Structured Clone Algorithm进行序列化,就像 window.postMessage,因此原型链将不会包含在内。 发送 Functions, Promises, Symbols, WeakMaps, 或 WeakSets 将抛出异常

注意: 发送非标准的 JavaScript 类型,如DOM 对象或特殊Electron 对象将会抛出异常。

主线程不支持 DOM 对象比如 ImageBitmap, File, DOMMatrix 等对象, 它们无法通过Electron的IPC发送到主线程,主要原因是主线程无法对他们进行解码 若尝试通过IPC发送这种对象数据将返回异常

主进程可以使用 ipcMain 监听 channel来接收这些消息,并通过 event.returnValue 设置回复消息。

⚠️ 警告: 发送同步消息将阻止整个渲染过程直到收到回复。 这样使用此方法只能作为最后手段。 使用异步版本更好 invoke()

ipcRenderer.postMessage(channel, message, [transfer])

  • channel string
  • message any
  • transfer MessagePort[] (optional)

发送消息到主进程,同时可以选择性发送零到多个 MessagePort 对象

从渲染进程发送到主进程的MessagePort对象可作为MessagePortMain对象访问触发事件的ports端口属性

例如:

// 渲染进程
const { port1, port2 } = new MessageChannel()
ipcRenderer.postMessage('port', { message: 'hello' }, [port1])

// 主进程
ipcMain.on('port', (e, msg) => {
const [port] = e.ports
// ...
})

更多关于如何使用 MessagePortMessageChannel的信息详见 MDN documentation

ipcRenderer.sendToHost(channel, ...args)

  • channel string
  • ...args any[]

就像 ipcRenderer.send,不同的是消息会被发送到 host 页面上的 <webview> 元素,而不是主进程。