Electron学习(6)Electron 渲染进程之间的通信

对于主进程和渲染进程之间的通信,查看官方API可以使用 IPC 是很方便的。但是渲染进程之间如何通信呢?
期初,刚开始以为ipcRenderer也能在渲染进程之间通信,但是我亲自测试之后发现并不可以。

  • 每个渲染进程都是统一由主进程启动,那么就可以采用主进程和渲染进程之间的消息转发来实现。
  • 渲染进程都是各个渲染进程中启动的,此时就会比较麻烦,这种情况有两种方式传递消息:
    a:使用ipcRenderer
    b:使用eventEmit

主进程和渲染进程之间消息转发

次方法的前提是,所有的渲染进程都是由主进程吊起的,可以获取每个渲染进程的BrowserWindow。原理是渲染进程B发送消息给主进程,主进程在转发消息给渲染进程A

// In renderer process B
ipcRenderer.send('message', 'someArgs')

// In the main process.
ipcMain.on('message', (event, arg) => {
  rendererAWindow.webContents.send('message', arg);
})

// In renderer process A
ipcRenderer.on('messaget', (event, arg) => {
    // do something
})

渲染进程之间直接通信

当渲染进程A中启动了渲染进程B,此时渲染进程A中应该是有渲染进程B的BrowserWindow对象的,这种情况下,可直接通过BrowserWindow对象的webContents.send给渲染进程B发送消息

// In renderer process A
<script>
      const electron = require('electron');
      const remote = electron.remote;
      const BrowserWindow =  remote.BrowserWindow;
      const curWin = remote.getCurrentWindow();
      const ipcRenderer = electron.ipcRenderer;
      let childWin = null;

      $('h1').click(function () {
        childWin = new BrowserWindow({width:800,height:600});
        childWin.loadURL(`file://${__dirname}/sub.html`);
        global.subWinId = childWin.id;
        childWin.on('close',function(){
          childWin = null
        })
      });
      
      $('h2').click(function(){
        childWin.webContents.send('aaa','i am come form renderer process A')
      })
  </script>

  // In renderer process B
    <script>
        const electron = require('electron');
        const remote = electron.remote;
        const BrowserWindow = remote.BrowserWindow;
        const curWin = remote.getCurrentWindow();
        curWin.webContents.openDevTools();
        const ipcRenderer = electron.ipcRenderer;
        
        ipcRenderer.on('aaa',function(event,args){
            console.log(args)
        })
</script>

但是现在假如说,渲染进程B如何向渲染进程A发送消息呢?这个时候我们可以使用全局变量来实现,可以给渲染进程A起一个全局变量,之后直接调用electron自带的窗口发送消息的方法或者使用EventEmit发送消息

// electron自带的窗口发送消息的方法
  global.rendererAWindow.webContents.send('message', arg);

//此时也可以使用emit事件,因为每一个BrowserWindow实例都是一个eventEmit
 global.rendererAWindow.emit('message',arg)

这中方式虽然很简单,但是给全局变量绑定太多window对象会严重影响应用性能,所以可以考虑取各个渲染进程的id,并且绑定到global对象上,最后通过下面的方法直接发送消息

remote.BrowserWindow.fromId(global.winAId).webContents.send('aaa', 'someThing');

个人不建议将BrowserWindow对象绑定到global对象上。

其它几种方式,请自行选用,如有写的不对的地方,还请纠正,谢谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,156评论 19 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,258评论 6 13
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,412评论 0 6
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,110评论 25 709
  • 不知不觉的就剩下了…… 毕业工作3年,至今银行卡里只有上个月发的不到4000的工资。小心翼翼的到今天都不敢花,因为...
    宅千年阅读 355评论 0 1