Electron Renderer 进程:我啥时候应该清理 IPC 监听器

Posted

技术标签:

【中文标题】Electron Renderer 进程:我啥时候应该清理 IPC 监听器【英文标题】:Electron Renderer Process: When Should I Clean IPC ListenersElectron Renderer 进程:我什么时候应该清理 IPC 监听器 【发布时间】:2020-08-13 09:30:33 【问题描述】:

我有一个 Electron 应用程序,其渲染器进程 ReactJs 和一个 Redux 基础设施连接并同步应用程序的所有打开进程(一个主进程和多个渲染器进程)中的所有商店

Redux 同步通信是通过电子 IPC 实现的,所以我有几个监听器用于不同的通道,这些监听器是按渲染器进程(浏览器窗口)添加的

作为一个例子,下面是监听来自主进程的分派动作的代码:

export const listenToFromMainDispatchedActions = (store: Store, senderId: string): () => void => 
  const listener = (event: IpcRendererEvent, args: any): void => 
    if (!isValidAppAction(args)) 
      appLogger.warn('Received an invalid action form main!!!');
     else 
      const action: IAppReduxAction<any> = 
        ...args,
        meta: 
          ...args.meta,
          handler: ReduxActionHandler.RECEIVER,
        ,
      ;
      if (action.meta.senderId !== senderId) store.dispatch(action);
    
  ;

  ipcRenderer.on(IPCChannels.ACTION_DISPATCH, listener);
  appLogger.warn('STORE_DISPATCH', 'ADDED ACTION_DISPATCH');
  return (): void => 
    ipcRenderer.removeListener(IPCChannels.ACTION_DISPATCH, listener);
    appLogger.warn('STORE_DISPATCH', 'REMOVED ACTION_DISPATCH');
  ;
;

这段代码在我的index.tsx 文件中执行,如下所示:

// index.tsx
// ...
export const GLOBAL_SENDER_ID = uuidV4();
const store = storeCreator(
  level: 'renderer',
  reducer: renderersReducer,
  sagas: mainAppWindowSagas,
  senderId: GLOBAL_SENDER_ID,
);

const listenerRemover = listenToFromMainDispatchedActions(store, GLOBAL_SENDER_ID);
...

我的问题是,如何以及何时调用 listenerRemover() 以删除 IPC 侦听器的最佳方式是什么?

我试图捕捉不同的文档/窗口事件,如 beforeunload 等,但无济于事。 为了保持一切“顺利”,我实际上在应用程序启动时打开所需的窗口并隐藏它们,关闭窗口会隐藏它们而不是杀死它们,我意识到这是明智的有问题的事件,但我需要一种优雅地删除这些侦听器的方法,我在文档中没有发现任何有用的东西

提前致谢

【问题讨论】:

【参考方案1】:

所以我想出的解决方案如下:

在浏览器端/渲染器进程(在index.tsx)我执行以下操作:

// index.tsx (renderer process)
// ...
export const GLOBAL_SENDER_ID = uuidV4();
const store = storeCreator(
  level: 'renderer',
  reducer: renderersReducer,
  sagas: mainAppWindowSagas,
  senderId: GLOBAL_SENDER_ID,
);

const listenerRemover = listenToFromMainDispatchedActions(store, GLOBAL_SENDER_ID);

const cleanup = (): void => 
   appLogger.log('WINDOW CLOSING');
   listenerRemover();
   window.removeEventListener('beforeunload', cleanup);


window.addEventListener('beforeunload', cleanup)
...

在主进程中,我删除了所有 ipcMain 对应项:

// index.ts
import  app, ipcMain  from 'electron';
import main from './main'
// ....
app.whenReady()
  .then(main)
  .catch((error) => 
    appLogger.error(TAG, error);
  );

// .....
app.on('before-quit', () => 
  Object.values(IPCChannels).forEach(
    (channel) => 
      ipcMain.removeAllListeners(channel);
    
  );
  appLogger.log('CLEANED ALL IPCS');
  appLogger.log('Done, BYEBYE');
);


它似乎按预期工作,我设法在相关位置看到日志,虽然我不太确定这种方法的有效性,但我会在几天内不回答我的问题(今天是13.08.2020 12:15CEST)。

如果我在一周左右的时间内没有得到任何其他/更好的答案,我会接受我的答案作为正确答案。

【讨论】:

接受我自己的答案,因为今天没有其他更好的解决方案是 21.08.2020 15:53 CEST

以上是关于Electron Renderer 进程:我啥时候应该清理 IPC 监听器的主要内容,如果未能解决你的问题,请参考以下文章

Electron 渲染进程主进程通信 01

electron 中renderer.js中使用require('electron') 报错require is not defined

使用electron中遇到的问题总结

Electron 渲染进程主进程通信 02

在 html 中调用 electron 的函数 主进程的函数 nodejs

electron开发记录:应用基本框架解析