进程间通讯(IPC)工作流程
我们前面介绍了主进程中的 入口程序 和渲染进程中的 的基本声明方法和交互方式,接下来我们将结合实际需求介绍两种进程间通讯的详细工作流程。
本节提及的所有相关 API 均可查询 Editor.Ipc 主进程 API 和 。
在主进程中,主要使用
接口向特定面板发送消息。对于目前支持的单面板插件来说:
panelID
面板 ID,对于单面板扩展包来说,面板 ID 就是插件的包名,如foobar
message
是 IPC 消息的全名,如foobar:do-some-work
,我们推荐在定义 IPC 消息名时使用-
来连接单词,而不是使用驼峰或下划线。- 可选
args
,从第三个参数开始,可以定义数量不定的多个传参,用于传递更具体的信息到面板进程。 - 可选
timeout
,回调超时,只能配合回调方法一起使用,如果规定了超时,在消息发送后的一定时间内没有接到回调方法,就会触发超时错误。如果不指定超时,则默认的超时设置是 5000 毫秒。
面板向主进程发送消息
Editor.Ipc.sendToMain('message', [, ...args, callback, timeout])
主进程对面板和面板对主进程是最常见的两种消息发送方式,但实际上 IPC 不局限于不同的两类进程之间,我们可以把消息发送方式做以下归类:
- 任意进程对主进程
Editor.Ipc.sendToMain
- 任意进程对面板
Editor.Ipc.sendToPanel
- 任意进程对编辑器主窗口(也就是对主窗口里的所有渲染进程广播)
Editor.Ipc.sendToMainWin
- 任意进程对所有窗口(对包括弹出窗口在内的所有窗口渲染进程广播)
Editor.Ipc.sendToWins
- 任意进程对所有进程广播
Editor.Ipc.sendToAll
上述方法在两种进程里写法都是一致的,只要注意消息接收的对象是在渲染进程还是主进程,并选择对应的方法即可。详细的接口用法请参考上文的描述和本文最上面的 IPC 接口文档链接。
要在主进程或渲染进程中接受 IPC 消息,最简单的办法是在声明对象的 messages
字段中注册以 IPC 消息为名的消息处理方法。
面板渲染进程消息监听
module.exports = {
//...
messages: {
'my-message': function (event, ...args) {
//do some work
}
}
注册监听消息时,我们使用的消息名是省略了扩展包名的短命名,上述消息短名 my-message
在发送时应该是 Editor.sendToPanel('foobar:my-message')
和 Editor.sendToMain('foobar:my-messages')
。
可以看到主进程和渲染进程中监听 IPC 消息的函数声明方式是一致的,传入的第一个参数是一个 event
对象,我们可以通过这个对象发送回调。
其他消息监听方式
除了在 messages
字段内注册之外还可以使用 Electron 的 Ipc 消息接口来监听,形式上更灵活:
主进程中:
require('electron').ipcMain.on('foobar:message', function(event, args) {});
关于 Electron 的 IPC 接口可以参考 Electron API: ipcRenderer。
假如我们从主进程发送了一个消息:
在面板监听消息的方法中,我们可以使用 event.reply
来发送回调:
//packages/foobar/panel/index.js
Editor.Panel.extends({
messages: {
'greeting': function (event, question) {
console.log(question); //How are you?
if (event.reply) {
//if no error, the first argument should be null
event.reply(null, 'Fine, thank you!');
}
}
});
注意 event.reply
第一个参数是报错,没有错误时应该传入 null
,此外建议总是检查 event.reply
是否存在,如果发送消息时参数中不包含回调方法,则 event.reply
的检查将返回 undefined
,这种情况下调用 event.reply
会产生错误。
发送消息时的最后一个参数是超时时限,单位是毫秒,如果未指定超时时限,则使用默认的 5000 ms 超时限制。
从消息发送开始,在超过规定的时限后仍然没有接到消息监听方法中返回的回调的话,就会收到系统发送的超时错误回调: