關於 Electron 進程間通訊的一個小小實踐

Electron 是一個跨平臺桌面框架,它集成了 node.js 和 chromium,因此咱們能夠藉助 node.js 實現桌面客戶端訪問操做系統資源的功能(出於安全,瀏覽器是不能夠訪問操做系統的),而 chromium 容許咱們使用前端工具HTML、JS、CSS 甚至結合 React、Vue 等渲染出用戶界面。前端

用進程間通訊模擬實現 B/S 架構

B/S 即 ‘瀏覽器/服務器’ 架構。既然 Electron 由 node.js 和 chromium 集成, 把 Electron 的渲染進程直接看成客戶端瀏覽器進程,主進程看成服務器進程,把訪問操做系統資源、讀寫文件等都放在主進程裏,而渲染進程專心用於渲染頁面和向主進程‘請求’操做資源,主進程和渲染進程之間能夠實現進程間通訊,能夠模擬瀏覽器和服務器之間的 ajax 請求。node

一個結合 Electron 的項目架構:git

下面以一個獲取 github 用戶信息和遠程倉庫的 Electron APP 爲例,用具體的代碼來展現如何實現github

渲染進程裏使用 ipcRenderer 封裝一個類 api 請求:web

// render/api.js

var electron = window.electron
var { ipcRenderer } = electron
import ipc_channel from '../const/ipc_channel'

export default {
  loginGithub: ({username, password, cb}) => { // 登陸 github 以建立一個 token
  // 向主進程請求登陸 GitHub
    ipcRenderer.send(ipc_channel.LOGIN_GITHUB, {username, password})

 // 主進程完成登陸後返回登陸響應(好比一個token)
    ipcRenderer.on(ipc_channel.LOGIN_GITHUB, (e, res) => {
      cb(res)
    })
  },
  logoutGithub: ({username, password, id, cb}) => { // 退出登陸
    ipcRenderer.send(ipc_channel.LOGOUT_GITHUB, {username, password, id})

    ipcRenderer.on(ipc_channel.LOGOUT_GITHUB, (e, res) => {
      cb(res)
    })
  } 
}
複製代碼

主進程使用 ipcMain 將渲染進程的各個請求路由到相應的路由處理器,而且傳遞一個回調函數方便路由處理器向渲染進程發送響應:ajax

//main.js

const routes = require('./server-routes/routes')

for(let routeName in routes) {
  ipcMain.on(routeName, (e, params) => {// 監聽渲染進程各個 ‘請求’
    routes[routeName]({ // 路由
      params, // 請求參數
      cb: (respond) => {// 回調函數用於向渲染進程發送響應
        e.sender.send(routeName, respond)}
      })
    })
}

複製代碼

路由處理器:後端

// server-routes/routes.js

var github = require('octonode')// octonode 是一個 GitHub API 封裝庫
var ipc_channel = require('../../const/ipc_channel')
const fs = require('fs')

const {getABranchContent, readLocalDir_OR_FileWithPath, readAFile} = require('./middleweres')

module.exports = {
  [ipc_channel.LOGIN_GITHUB]: ({params, cb}) => {
    let {username, password} = params

    var scopes = {
      'scopes': ['user', 'repo', 'gist'],
      'note': 'admin script'
    }
    
    github.auth.config({
      username,
      password
    }).login(scopes, function (err, id, token, headers) {
      console.log(id, token)
      if(!err) cb({id, token})
    })
  },

  [ipc_channel.LOGOUT_GITHUB]: ({params, cb}) => {
    let {username, password, id} = params

    github.auth.config({
      username,
      password
    }).revoke(id, function (err) {
      if (err) throw err
      else cb({msg: '已經退出登陸'})
    })
  }
}
複製代碼

用一個單獨的文件導出各個 ipc channel:api

// ipc_channel.js

module.exports = {
    LOGIN_GITHUB: 'login-github-for-token', // 登陸 GitHub 以獲取 token
    LOGOUT_GITHUB: 'logout-and-revoke-token', // 退出登陸並銷燬 token
    GET_REPO: 'get-a-repo', // 獲取 github 上某個倉庫的內容
    READ_LOCAL_PATH: 'read-local-path', // 讀取本地目錄
    READ_LOCAL_FILE: 'read-local-file', // 讀取本地文件
    READ_LOCAL_REPO_INFO_FILE: 'read-repo-info-file' // 讀取存儲在本地的倉庫的信息
}
複製代碼

這樣借鑑了 web 中先後端分離的思想,我的認爲能夠很清晰的分離應用的邏輯。瀏覽器

本文的素材源自我的的 Electron 小項目:github-repo-viewer安全

相關文章
相關標籤/搜索