0
点赞
收藏
分享

微信扫一扫

如何在Electron App中运行后台工作进程(Hidden Renderers)


如何在Electron App中运行后台工作进程(Hidden Renderers)

最近使用electron开发一个图片识别的软件,涉及到后台执行大量的运算,所以这里介绍一种使用Hidden Renderers执行后台进程的一种方式

由于我从接触electron和typescript到写这篇文章只有两天,可能存在错误,请指出

Electron是一个流行的框架,可以使用Web技术(如HTML,CSS和JavaScript)来创建跨平台的桌面应用程序。Electron应用程序由两种类型的进程组成:主进程和渲染进程。主进程负责管理应用程序的生命周期,创建和控制浏览器窗口,以及与操作系统交互。渲染进程负责在浏览器窗口中显示Web页面,并执行其中的JavaScript代码。

有时,我们可能需要在Electron应用程序中运行一些后台工作,例如处理大量数据,执行复杂的计算,或者与远程服务器通信。这些工作可能会消耗大量的CPU和内存资源,从而影响渲染进程的性能和用户体验。为了避免这种情况,我们可以使用后台工作进程来在单独的线程中执行这些工作,从而不干扰主进程和渲染进程。

后台工作进程是一种特殊的渲染进程,它不显示任何Web页面,而是只运行JavaScript代码。它可以通过IPC(Inter-Process Communication)机制与主进程和其他渲染进程通信。Electron提供了两种方式来创建和管理后台工作进程:Web Workers和hidden renderers

hidden renderers是一种特殊类型的渲染进程,它们不显示任何窗口或图形界面,但可以访问Node.js和Electron API,以及Web API。您可以使用hidden renderers来执行任何您想要在后台运行的任务,并通过IPC(进程间通信)与主进程或其他渲染进程交换数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BLnOln21-1680270568043)(https://lzx-figure-bed.obs.dualstack.cn-north-4.myhuaweicloud.com/Figurebed/202303312139422.png)]

  • 第一步创建隐藏窗口:

let mainWindow, workerWindow;
function createWindow() {
  // 创建主窗口
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: { nodeIntegration: true }
  });
  mainWindow.loadFile('index.html');
  // 创建隐藏的工作窗口
  workerWindow = new BrowserWindow({
    show: false,
    webPreferences: { nodeIntegration: true }
  });
  workerWindow.loadFile('worker.html');
  [...]
}

这是一段使用 Electron 框架创建窗口的代码片段。这段代码创建了两个窗口,一个是主窗口,一个是工作窗口。

代码中的 BrowserWindow 是 Electron 提供的一个类,用于创建桌面应用程序中的窗口。createWindow 函数包含两个 BrowserWindow 对象的创建和配置。

主窗口使用 loadFile 方法加载名为 index.html 的本地 HTML 文件。主窗口的大小被设置为 800x600 像素,并启用了 Node.js 集成,这意味着在主窗口中可以使用 Node.js 模块。

工作窗口也被创建为 BrowserWindow 对象,并使用 loadFile 方法加载名为 worker.html 的本地 HTML 文件。但与主窗口不同的是,工作窗口被设置为不显示,这意味着用户将无法看到该窗口。

  • worker.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>I'm a hidden worker</title>
  </head>
  <body>
    <script>
      // your background code here
    </script>
  </body>
</html>

  • 第二步进程通信
    在 Electron 中,有两种主要的进程类型:主进程和渲染进程。主进程负责管理应用程序的生命周期和与操作系统的交互,而渲染进程则负责显示和交互用户界面。
    主进程可以通过渲染进程的 “webContents” 对象与任何渲染进程通信。 “webContents” 对象是渲染进程中显示网页内容的对象,主进程可以使用它来发送消息和监听事件。
    渲染进程与主进程之间的通信需要使用 IPC(进程间通信)通道。IPC 通道是一种在 Electron 中用于不同进程之间通信的机制,渲染进程可以使用它来向主进程发送消息和请求数据。
    最后,需要注意的是,渲染进程之间不能直接通信。如果两个渲染进程需要通信,它们必须通过主进程进行中转。
  • 在工作进程中,我们使用Electron的IPC Renderer模块向主进程发送消息。我们定义了一个名为message2UI的函数,该函数将消息发送到名为message-from-worker的频道,消息本身包含命令和载荷部分。

const electron = require('electron');
const ipcRenderer = electron.ipcRenderer;

function message2UI(command, payload) {
  ipcRenderer.send('message-from-worker', { command, payload });
}

message2UI('helloWorld', { myParam: 1337, anotherParam: 42 });

在主进程中,我们需要添加一个处理程序来处理通过message-from-worker通道传入的消息。我们创建了一个名为sendWindowMessage的函数,该函数使用webContents对象将消息转发到目标进程。在app.on(‘ready’)回调中,我们使用IPC Main模块来侦听message-from-worker通道的消息,并将其转发到主窗口(mainWindow)。

const { ipcMain } = require('electron');

function sendWindowMessage(targetWindow, message, payload) {
  if(typeof targetWindow === 'undefined') {
    console.log('Target window does not exist');
    return;
  }
  targetWindow.webContents.send(message, payload);
}

app.on('ready', () => {
  // ...
  ipcMain.on('message-from-worker', (event, arg) => {
    sendWindowMessage(mainWindow, 'message-from-worker', arg);
  });
  // ...
});

最后,在渲染进程中,我们需要添加一个监听器来接收通过message-from-worker通道传入的消息。我们可以使用IPC Renderer模块中的on方法来实现这一点。

const { ipcRenderer } = require('electron');
ipcRenderer.on('message-from-worker', (event, arg) => {
  console.log(arg.command); // 输出:helloWorld
  console.log(arg.payload); // 输出:{ myParam: 1337, anotherParam: 42 }
});


举报

相关推荐

0 条评论