为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

翻翻过去那场雪 2023-01-06 15:54:20

我有一个 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 回答

?
天涯尽头无女友

TA贡献1590条经验 获得超9个赞

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


在浏览器端/渲染器进程(在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)。


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


查看完整回答
反对 回复 2023-01-06
  • 1 回答
  • 0 关注
  • 8 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信