项目中JSSDK封装方案

前言

这是入职之后,在公司项目中,梳理的jssdk封装的方案,其中一些方法例如:ipcRenderer.sendTo()已经在新版的eletron中弃用,其中的方案仅供学习。有不对的地方也欢迎各位大佬指正

弃用:ipcRenderer.sendTo()

ipcRenderer.sendTo() 已被弃用。 可以通过在渲染器之间设置一个MessageChannel 来替换它。 IpcRendererEventsenderIdsenderIsMainFrame 属性也已被弃用

后面,项目中还引入了模块联邦,这一块还没有梳理到,我会在之后补充进文档当中。

一、SDK工作流程图

什么是jssdk?它描述是一个工具集合,能够帮助我们快速调用各种能力,其包含了各种api,有自己的api文档和调用案例。

二、SDK整体架构设计

sdk主要配置路径/src/11-renderer/_public/sdk

其目录架构组成为:

2.1、通信桥接层

在/msgbridge.ts文件下,这里负责处理收到的postmsg,处理不同窗口间的postMessage通信,同时支持webView和BrowserView等场景(还有模块联邦)的通信,进行统一的消息处理、参数处理和api鉴权。

webView

ts 复制代码
// 处理发送postmg
// containerId:目标窗口id
// msgdata:传递的参数
export function handlePostMessage({ msgdata, containerId }: { msgdata: any; containerId: any }) {
    const { url, webview } = getWebviewUrl(containerId);
    webview && webview.contentWindow.postMessage(msgdata, url);
}

BrowserView

ts 复制代码
function handleBrowserViewMessage({ msgdata, containerId }: { msgdata: any; containerId: any }) {
    window.ELECTRONCHANNEL &&
        window.ELECTRONCHANNEL.electronBrowserviewSendToData({ ...msgdata, view_id: containerId });
}

2.2. 状态管理层

/redux.js 进行状态管理适配,可以根据不同的apicaller动态加载对应的redux模块

2.3. API层

csharp 复制代码
api/
 --biz/            # 业务相关API
    -- util/       # 工具类API
    -- chat/       # 聊天相关
    -- contact/    # 联系人相关
    -- group/      # 群组相关
    -- navigation/ # 导航相关
 --device/         # 设备相关API
 --runtime/        # 运行时API
 --primary/        # 基础API
 --noPoint/        # 免鉴权API
 --util/           # 通用工具

2.4. 文件处理系统

/file目录下封装了对文件的处理的方法,比如视频转码、视频播放、文件预览、文件下载等功能

2.5. 事件系统

在目录/yach-event下,封装了ai助手调用、addContentToEditor、toggleAddPrompt等方法。

三、如何建立通信

通信的建立包括四个步骤:preload脚本注入、H5调用、Yach接收调用、H5接收返回。

大致流程图如下:

从两种情况出发,webView和BrowserView,在我们注入脚本的时候,sendTo和sendToHost两个方法的应用场景也不同。

3.1 sendTo

官方:ipcRenderer.sendTo() 已被弃用。 可以通过在渲染器之间设置一个 MessageChannel 来替换它。

需要明确指定目标渲染进程的容器id

javascript 复制代码
ipcRenderer.sendTo(win.id, '事件名', JSON.stringfy(data))

大致通信过程

1、主进程获取容器id并且发送给需要通信的进程

ts 复制代码
// 主进程
const winA = new BrowserWindow();
const winB = new BrowserWindow();
// 向 winA 传递 winB 的 ID
winA.webContents.send('target-id', winB.webContents.id);

2、渲染进程A向进程B发送消息

ts 复制代码
//渲染进程A
ipcRenderer.on('target-id', (event, targetId) => {
  ipcRender.sendTo(targetId, 'test', '这是A发送的消息')
})

3、渲染进程B接收消息

ts 复制代码
//渲染进程B
ipcRenderer.on('test', (event, message) => {
  console.log(message)//输出这是A发送的消息
})

3.2 sendToHost

无需指定目标容器id,默认发送给当前渲染进程的"主容器"(通常是主进程创建的容器页面)

arduino 复制代码
ipcRenderer.sendToHost('事件名', '消息');

大致通信流程

1、渲染进程

ts 复制代码
// 渲染进程(网页)
ipcRenderer.sendToHost('test', '这是渲染进程的消息');

2、主进程进行监听并且处理

ts 复制代码
const win = new BrowserWindow({
  webPreferences: { nodeIntegration: false}// 限制渲染进程权限
});
//监听sendToHost发送的消息
wind.webContents.on('ipc-message',(event, channel, args) => {
  if(channel === 'test'){
    //处理并返回结果
    event.sender.sendToHost('result', {list: [...]})
  }
})

3、渲染进程接收宿主消息

ts 复制代码
//渲染进程
ipcRenderer.on('result', (event, data) => {
  console.log(data); //输出: 主进程返回的list
})

3.3 webView

webView是一个嵌入在渲染进程中的"子浏览器窗口",内部运行独立的渲染进程,且具有严格的沙箱隔离。通常使用senToHost方法。

webView内部页面的"宿主"是外层的渲染进程或者主进程,sendToHost设计的初衷就是让子页面向宿主发送消息,无需关心宿主的具体窗口id,简化通信链路。

3.4 browserView

browserView是由主进程创建、直接挂载到主窗口的"原生视图",没有独立的沙箱,其通信通过主进程的webContents直接交互,通常使用sendTo方法

browserView是由主进程管理,其webContent有明确的id,可以通过browserView。webContent.id获取。主进程或者其他渲染进程可通过sendTo(id, message)直接向其发消息。

相关推荐
peachSoda71 小时前
封装一个不同跳转方式的通用方法(跳转外部链接,跳转其他小程序,跳转半屏小程序)
前端·javascript·微信小程序·小程序
没有bug.的程序员1 小时前
服务治理与 API 网关:微服务流量管理的艺术
java·分布式·微服务·架构·wpf
@PHARAOH1 小时前
HOW - 浏览器兼容(含 Safari)
前端·safari
undefined在掘金390411 小时前
flutter 仿商场_首页
前端
少卿1 小时前
react-native图标替换
前端·react native
熊猫钓鱼>_>1 小时前
TypeScript前端架构与开发技巧深度解析:从工程化到性能优化的完整实践
前端·javascript·typescript
Guheyunyi2 小时前
风险感知中枢:监测预警系统的架构与核心
大数据·运维·安全·重构·架构·自动化
JYeontu2 小时前
肉眼难以分辨 UI 是否对齐,写个插件来辅助
前端·javascript
fox_2 小时前
别再踩坑!JavaScript的this关键字,一次性讲透其“变脸”真相
前端·javascript
盛夏绽放2 小时前
uni-app Vue 项目的规范目录结构全解
前端·vue.js·uni-app