electron系列:第一回
本系列开始,将逐步介绍前端的客户端经典框架–electron(系列文章)
本文主要讲解electron的通信机制
首先祭出一张经典的图:
electron有且只有一个主进程,由package.json中的main字段定义,Electron 使用 Chromium 来展示 web 页面,每个页面运行在自己的渲染进程中。
一. 为什么这么划分
根本逻辑:主进程拥有服务器端的能力,例如读写文件资源,渲染进程负责页面呈现。
二. 基本配置
1. 创建app,主进程设置ipcMain,用来监听渲染进程事件
import { app, BrowserWindow, ipcMain } from 'electron'
import { handleGetAllCates, handleGetAllItems, handleGetVideo, getVideoContentVersionTwo } from '../src/utils/videoApi'
const fs = require('fs')
let mainWindow: BrowserWindow | null
declare const MAIN_WINDOW_WEBPACK_ENTRY: string
declare const MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY: string
function createWindow () {
mainWindow = new BrowserWindow({
width: 1100,
height: 700,
backgroundColor: '#191622',
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: MAIN_WINDOW_PRELOAD_WEBPACK_ENTRY
}
})
mainWindow.loadURL(MAIN_WINDOW_WEBPACK_ENTRY)
mainWindow.on('closed', () => {
mainWindow = null
})
}
async function registerListeners () {
/**
* This comes from bridge integration, check bridge.ts
*/
ipcMain.on('message', (event: any, message: any) => {
console.log('main-get>>', message)
switch(message.type) {
case 'getAllCates':
handleGetAllCates(event, message)
break;
case 'getAllVideosInCate':
handleGetAllItems(event, message)
break;
case 'getVideoContent':
handleGetVideo(event, message)
// getVideoContentVersionTwo(event, message)
break;
default:
break;
}
})
}
app.on('ready', createWindow)
.whenReady()
.then(registerListeners)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
通过上面code,我们创建了一个app,关注其中的重点ipcMain, 这是用来前后通信的关键。我们在registerListeners中注册了on事件,用来接收渲染器进程的请求。
2. ipcRenderer设置监听响应函数,并挂载到全局window上
import { contextBridge, ipcRenderer } from 'electron'
import { IPCInfo } from '../src/utils'
export const api = {
sendMessage: (message: IPCInfo) => {
ipcRenderer.send('message', message)
},
on: (channel: string, callback: Function) => {
ipcRenderer.on(channel, (_, data) => callback(data))
}
}
contextBridge.exposeInMainWorld('Main', api)
之后渲染进程的消息收发均通过window.Main
3. 主进程接收到渲染进程的请求, 读取对应资源,再通过event.sender.send接口返回读取的内容,完成一次资源请求。
export const handleGetVideo = (event: any, message: any) => {
console.log('handleGetVideo>>>', message)
const path = message.data.path
// console.log('path>>', path)
fs.readFile(path, (err: Error, data: any) => {
// console.log('读取文件内容>>>', data)
event.sender.send('getVideoContent_back', {
name: message.data.name,
file: data
})
})
}
总而言之, electron能够让我们具备这样一种能力: 整合前后端的能力, 开发客户端软件。
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
