摘要:為了能使不同的進程互相訪問資源并進行協(xié)調(diào)工作,才有了進程間通信。此時,就需要與渲染進程通信了。發(fā)消息,渲染進程收消息內(nèi)部使用來發(fā)消息。
前言作者:鐘離,酷家樂PC客戶端負責人
原文地址:https://webfe.kujiale.com/electron-ku-jia-le-ke-hu-duan-kai-fa-shi-jian-fen-xiang-jin-cheng-tong-xin/
酷家樂客戶端:下載地址 https://www.kujiale.com/activity/136
文章背景:在酷家樂客戶端在V12改版成功后,我們積累了許多的寶貴的經(jīng)驗和最佳實踐。前端社區(qū)里關(guān)于Electron知識相對較少,因此希望將這些內(nèi)容以系列文章的形式分享出來。
系列文章:【Electron】酷家樂客戶端開發(fā)實踐分享 — 入坑篇
【Electron】酷家樂客戶端開發(fā)實踐分享 — 軟件自動更新
【Electron】酷家樂客戶端開發(fā)實踐分享 — 瀏覽器啟動客戶端
【Electron】酷家樂客戶端開發(fā)實踐分享 — 進程通信
【Electron】酷家樂客戶端開發(fā)實踐分享 — 下載管理器
不定期更新...
Electron中的進程,其實就是計算機中的進程,我們先來看看什么是進程通信
進程間通信(IPC,Inter-Process Communication),指至少兩個進程或線程間傳送數(shù)據(jù)或信號的一些技術(shù)或方法
每個進程都有自己的一部分獨立的系統(tǒng)資源,彼此是隔離的。為了能使不同的進程互相訪問資源并進行協(xié)調(diào)工作,才有了進程間通信。
一個Electron應(yīng)用有一個主進程和多個渲染進程,渲染進程還可能內(nèi)嵌多個webview。兩兩之間都可能需要進行通信,情況還是比較復雜的。
需要通信的對象主進程: 使用ipcMain進行通信
渲染進程: 使用ipcRenderer和remote模塊進行通信
webview: 一般會禁用webview的node集成,然后使用preload的方式拿到ipcRenderer來做進程通信。
// preload.js const electron = require("electron"); const { ipcRenderer } = electron; // 把ipcRenderer掛載到window上,webview內(nèi)部的js可以拿到這個模塊 window.ElectronIpcRenderer = ipcRenderer;ipcRenderer/ipcMain VS remote
主進程和渲染進程通信方式,擰出來多帶帶說一下。先來看一個簡單例子的:
點擊創(chuàng)建按鈕,創(chuàng)建一個新的窗口。點擊關(guān)閉按鈕,關(guān)掉這個新窗口。
左側(cè)代碼使用ipcRenderer/ipcMain進行通信,右側(cè)代碼使用remote進行通信。實現(xiàn)的功能都是一樣的。從這個例子中可以發(fā)現(xiàn):
使用ipcMain/ipcRenderer通信,業(yè)務(wù)邏輯同時存在于主進程和渲染進程的代碼中。同時為了通信,會產(chǎn)生非常多的event & event handler。
使用remote通信,渲染進程直接獲取主進程模塊。而且,使用remote通信不需要使用事件和回調(diào)函數(shù),寫出來的代碼清晰直觀。
主進程可以視作為模塊提供者,而渲染進程是模塊的消費者,渲染進程通過remote來獲取主進程的模塊,實現(xiàn)業(yè)務(wù)邏輯。這樣做有以下好處:
主進程/渲染進程代碼解耦,職責分明,提升可維護性
業(yè)務(wù)邏輯內(nèi)聚在渲染進程
減少主進程/渲染進程冗余無用的代碼
具體實現(xiàn)介紹了一下前置知識,現(xiàn)在來看看不同情況下,Electron進程通信的實現(xiàn)方法。
主進程和渲染進程通信主進程發(fā)消息、渲染進程收消息:主進程使用窗口的webContents發(fā)消息,渲染進程內(nèi)使用ipcRenderer收消息
// main.js const win = new BrowserWindow(); win.load("index.html"); win.webContents.send("hello", {a: 1}); // index.html 中的js const { ipcRenderer } = require("electron"); ipcRenderer.on("hello", (e, data) => { console.log(data); // 打印出 {a: 1} })
渲染進程發(fā)消息、主進程收消息: 渲染進程使用ipcRenderer發(fā)消息,主進程使用ipcMain收消息。
// main.js const { ipcMain } = require("electron"); ipcMain.on("hello", (e, data) => { console.log(data); // 打印出 {a: 1} }); // index.html 中的js const { ipcRenderer } = require("electron"); ipcRenderer.send("hello", {a: 1});
一般遇到主進程和渲染進程通信的情況,大部分都是渲染進程來需要獲取主進程的模塊,此時推薦使用remote來做通信。
// main.js // 主進程無需添加任何代碼 // index.html 中的js,獲取主進程模塊 const { remote } = require("electron"); const {app, BrowserWindow, dialog, ...} = remote;渲染進程與渲染進程通信
渲染進程之間也是會頻繁通信的,具體場景舉例:在設(shè)置窗口點擊更換皮膚,需要通知所有窗口進行顏色、背景的更新。
最佳實踐:渲染進程A通過remote模塊,獲取到需要目標窗口的webContents對象,然后通過webContents向目標窗口的發(fā)送消息。目標窗口使用ipcRenderer監(jiān)聽事件。
const { remote } = require("electron") const allWindows = remote.BrowserWindow.getAllWindows(); // 窗口A中的邏輯 // 1、第一步,獲取到目標窗口的webContents // 可以根據(jù)id,title來找到目標窗口,也可以用其他辦法 const targetId = 1; const targetTitle = "目標窗口"; // let targetWindow = allWindows.find(w => w.id === targetId); let targetWindow = allWindows.find(w => w.title === targetTitle); // 2、第二步,使用目標窗口的webContents發(fā)送消息 targetWindow.webContents.send("theme-change", "gray"); // 目標窗口內(nèi)的邏輯,使用ipcRenderer監(jiān)聽事件 // 窗口收到theme-change事件,改變窗口顏色。不需要關(guān)注事件從哪里發(fā)出,只需要關(guān)注接收到該事件后做什么 ipcRenderer.on("theme-change", (e, theme) => { console.log(theme); // gray });
還有一種傳統(tǒng)的辦法,不用remote,改用ipcMain做通信,但是會在主進程冗余很多事件代碼。因此還是推薦使用remote,理由同上。小例子:
// mian.js // 用于事件轉(zhuǎn)發(fā),沒有實際的邏輯 ipcMain.on("send-event-to-window", (e, id, eventName, ...args) => { BrowserWindow.getAllWindows() .find(w = > w.id === id) .webContents .send(eventName, ...args); }); // 窗口A內(nèi)部,向主進程發(fā)事件 const targetId = 1; ipcRenderer.send("send-event-to-window", id, "theme-change", "gray"); // 目標窗口 ipcRenderer.on("theme-change", (e, theme) => { console.log(theme); // gray });webview與渲染進程通信
內(nèi)嵌的web頁面運行在客戶端中,也可以獲取本地化的能力。此時,webview就需要與渲染進程通信了。
在文章開頭講到了,為了應(yīng)用的安全性webview是需要禁用node集成的,通過preload的方式,注入了一個ipcRenderer并掛載到window上。
webview發(fā)消息,渲染進程收消息:webview內(nèi)部使用ipcRenderer.sendToHost來發(fā)消息。渲染進程獲取到webview的dom元素,監(jiān)聽dom元素的ipc-message事件接收消息
// 渲染進程拿到webview的dom,接收事件 const webview = document.querySelector("webview") webview.addEventListener("ipc-message", (event) => { console.log(event.channel); // hello }); // webview頁面內(nèi),假裝點了一個按鈕,發(fā)送事件 btn.onclick = () => { window.ElectronIpcRenderer.sendToHost("hello") }
渲染進程發(fā)消息,webview收消息:渲染進程使用webview.send發(fā)消息。webview使用內(nèi)置的ipcRenderer收消息。
// webview內(nèi)部 window.ElectronIpcRenderer.on("event-from-renderer", (e, data) => { console.log(e, data); // {a: 1} }); // 渲染進程內(nèi)部 const webview = document.querySelector("webview") webview.send("event-from-renderer", {a: 1})總結(jié)
這三種通信方式是最基礎(chǔ)的,在此之上進行排列組合也是很常見的,這個由開發(fā)者自行拓展即可。
舉一個小例子:webview內(nèi)部觸發(fā)更換皮膚功能 -> 通知渲染進程同步更新皮膚 -> 渲染進程收到消息,向其他渲染進程通信 -> 同步更新皮膚完成。
最后歡迎大家在評論區(qū)討論,技術(shù)交流 & 內(nèi)推 -> [email protected]
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/54044.html
摘要:為了能使不同的進程互相訪問資源并進行協(xié)調(diào)工作,才有了進程間通信。此時,就需要與渲染進程通信了。發(fā)消息,渲染進程收消息內(nèi)部使用來發(fā)消息。 作者:鐘離,酷家樂PC客戶端負責人原文地址:https://webfe.kujiale.com/electron-ku-jia-le-ke-hu-duan-kai-fa-shi-jian-fen-xiang-jin-cheng-tong-xin/酷家...
摘要:為了能使不同的進程互相訪問資源并進行協(xié)調(diào)工作,才有了進程間通信。此時,就需要與渲染進程通信了。發(fā)消息,渲染進程收消息內(nèi)部使用來發(fā)消息。 作者:鐘離,酷家樂PC客戶端負責人原文地址:https://webfe.kujiale.com/electron-ku-jia-le-ke-hu-duan-kai-fa-shi-jian-fen-xiang-jin-cheng-tong-xin/酷家...
摘要:系列文章酷家樂客戶端開發(fā)實踐分享入坑篇酷家樂客戶端開發(fā)實踐分享軟件自動更新酷家樂客戶端開發(fā)實踐分享瀏覽器啟動客戶端酷家樂客戶端開發(fā)實踐分享進程通信酷家樂客戶端開發(fā)實踐分享下載管理器不定期更新本文的初衷所使用的技術(shù)棧和前端工程師完美契合。 作者:鐘離,酷家樂PC客戶端負責人原文地址:https://webfe.kujiale.com/electron-ku-jia-le-ke-hu-d...
摘要:系列文章酷家樂客戶端開發(fā)實踐分享入坑篇酷家樂客戶端開發(fā)實踐分享軟件自動更新酷家樂客戶端開發(fā)實踐分享瀏覽器啟動客戶端酷家樂客戶端開發(fā)實踐分享進程通信酷家樂客戶端開發(fā)實踐分享下載管理器不定期更新本文的初衷所使用的技術(shù)棧和前端工程師完美契合。 作者:鐘離,酷家樂PC客戶端負責人原文地址:https://webfe.kujiale.com/electron-ku-jia-le-ke-hu-d...
摘要:作者鐘離,酷家樂客戶端負責人原文地址酷家樂客戶端下載地址文章背景在酷家樂客戶端在改版成功后,我們積累了許多的寶貴的經(jīng)驗和最佳實踐。用戶在電腦上安裝客戶端,實際上會將客戶端代碼文件持久儲存到本機。通常我們會在軟件啟動時檢查更新。 作者:鐘離,酷家樂PC客戶端負責人原文地址:https://webfe.kujiale.com/electron-autoupdate/酷家樂客戶端:下載地址...
閱讀 3907·2021-11-22 13:54
閱讀 2680·2021-09-30 09:48
閱讀 2363·2021-09-28 09:36
閱讀 3117·2021-09-22 15:26
閱讀 1346·2019-08-30 15:55
閱讀 2513·2019-08-30 15:54
閱讀 1427·2019-08-30 14:17
閱讀 2344·2019-08-28 18:25