【问题标题】:Electron IPC excessive messagesElectron IPC 过多消息
【发布时间】:2016-01-03 22:30:05
【问题描述】:

我正在尝试在 Electron(atom shell)平台上构建桌面应用程序,目前在 mac os x 上。

我正在尝试它的 IPC(进程间通信)模块,用于在两个主要电子进程(主进程和渲染器进程)之间发送和接收同步和异步消息。

但是,对于异步消息,我从渲染器进程发送到主进程的消息得到了超出预期的答复,并在主进程中得到答复。我知道控制台输出主进程的回复应该产生的这种形式。

对于 DOM 的 2 个组件中的每一个,我将 1 条消息发送到主进程,它会以一个记录到控制台的回复作为响应。但是对于 2 个组件(反应组件),我得到 4 个控制台日志行,3 个是 9 个,4 个是 16 个控制台日志消息行。

这里发生了什么?关于 IPC 的异步消息和回复,我缺少什么?同步消息和回复没有问题。

main.js(主进程代码):

var app = require('app');  // Module to control application life.
var BrowserWindow = require('browser-window');  // Module to create native browser window.
var ipc = require('ipc');

// Report crashes to our server.
require('crash-reporter').start();

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is GCed.
var mainAppWindow = null;
var bookWindow = null;

// Quit when all windows are closed.
app.on('window-all-closed', function() {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  app.quit();
});

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
  // Create the browser window.
  mainAppWindow = new BrowserWindow({width: 1200, height: 900, 'title-bar-style': 'hidden'});

  // and load the index.html of the app.
  mainAppWindow.loadUrl('file://' + __dirname + '/index.html');

  mainAppWindow.openDevTools();
  // Emitted when the window is closed.
  mainAppWindow.on('closed', function() {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainAppWindow = null;
    app.quit();
  });

  ipc.on('asynchronous-message', function(event, arg) {
    console.log(arg);  // prints "ping"
    event.sender.send('asynchronous-reply', 'pong');
  });


  // listen for the messages from renderer process to close the mainwindow and open a readerwindow
  ipc.on('synchronous-message', function(event, arg) {
    console.log(arg);  // prints "ping"
    event.returnValue = 'pong';
  });
  // when all of the book reader windows are closed open the mainAppWindow
  // in main process listen for all bookreaderwindows are closed
  // and in each, checking an array of them formed when they are each created.
});

index.js(渲染器进程代码):

/*
-mainApp
  -Controls
  -Books
    -Book
*/
var ipc = require('ipc');

var Book = React.createClass({
  switchToBookReader: function() {
    // close mainAppWindow, and open bookreader window.
    // send message to main process 'close window'.
    // listen in main process for this.
    // callback for this in main process is to close the main window and open a readerwindow
  },
  componentDidMount: function() {
    ipc.send('asynchronous-message', 'ping');
    ipc.on('asynchronous-reply', function(arg) {
      console.log(arg); // prints "pong"
    });
    console.log(ipc.sendSync('synchronous-message', 'ping')); // prints "pong"
  },
  render: function() {
    return (
      <div onDoubleClick={this.switchToBookReader()} >
        {this.props.name}
      </div>
    );
  }
});

var Books = React.createClass({
  render: function() {
    // create Book nodes here.
    var bookNodes = [];
    bookNodes.push(<Book name="book1"/>);
    bookNodes.push(<Book name="book2"/>);


    return (
      <div>
        {bookNodes}
      </div>
    );
  }
});

var Controls = React.createClass({
  render: function() {
    return (
      <div>
        Controls
      </div>
    );
  }
});

var mainApp = React.createClass({
  render: function() {
    return (
      <div>
        <Controls />
        <Books />
      </div>
    );
  }
});

React.render(<mainApp />, document.body);

【问题讨论】:

  • 等等!渲染器进程中的 2 个侦听 &lt;Book&gt; 组件的答案是否捕获了来自主进程的异步 2 回复,以及这 2 个进程中的每一个的 2 个组件控制台日志中的每一个? 2 条消息发送到 main,它触发了 2 个回复,渲染器中的 2 个组件监听,每个组件捕获每个 2 个日志 2 个控制台日志,加起来是 4,监听组件数量的平方。
  • 任何人都可以解决这个问题..

标签: javascript asynchronous electron dom-events


【解决方案1】:

每个监听器都会创建一个唯一的 ID,该 ID 在创建监听器时会返回。基于此,可以像这样删除监听器:

ipcRenderer.once(channel, listener);

为事件添加一次性监听函数。仅在下一次将消息发送到通道时调用此侦听器,然后将其删除。

访问https://electron.atom.io/docs/api/ipc-renderer/#ipcrendereroncechannel-listener

在这里找到了解决方案并开始工作。

【讨论】:

    猜你喜欢
    • 2017-07-08
    • 2021-09-13
    • 2017-03-17
    • 2021-08-21
    • 2022-01-11
    • 2012-05-26
    • 2012-09-19
    • 2021-03-12
    • 2020-10-25
    相关资源
    最近更新 更多