electron-ipc-decorators:让你的Electron桌面应用主进程和渲染进程通信变得简单精彩
如果你是一个Electron的web桌面开发者,又想简化IPC通信开发,推荐你上手体验这个框架。装饰器、自动扫描、性能优化,让你开发更高效和专注,进阶到全新的Electron主进程和渲染进程通信高度。
前言
如果你是一个Electron的web桌面开发者,又想简化IPC通信开发,推荐你上手体验这个框架。装饰器、自动扫描、性能优化,让你开发更高效和专注,进阶到全新的Electron主进程和渲染进程通信高度。
一、是什么?
这是一个用于在Electron的主进程和渲染进程之间进行IPC通信的框架。它具有以下功能:
在渲染进程中
- 使用
@ipc
装饰器可以方便地发起对主进程方法的远程调用。 IPCProxy
类实现了与主进程通信的接口,并在内部使用@ipc
装饰器发起远程调用。
在主进程中
- 使用@IpcMapping装饰器可以给类添加IpcMapping元数据,指定这个类所在的IPC通信group。
- IPCManager类用于注册IPC通信监听和处理程序。
- 有一个自动扫描机制,会扫描所有的
*.ipc.ts
文件,找到@IpcMapping
装饰过的类,并自动注册这个类的所有方法作为IPC通信的处理程序。
二、使用步骤
举个例子,有一个UserQuery接口和实现:
类图如下
代码如下
interface IUserQuery {
selectById(id: string): Promise<string>
}
@IpcMapping("IUserQuery")
class UserQueryIpc implements IUserQuery {
selectById(id: string) { ... }
}
然后在渲染进程中,可以这样使用:
class UserQueryProxy implements IUserQuery {
@ipc("IUserQuery")
selectById(id: string) { ... }
}
const userQuery = new UserQueryProxy()
userQuery.selectById("1").then(res => { ... })
这个调用会远程调到主进程的UserQueryIpc.selectById
方法。
所以通过这个框架,主进程和渲染进程之间的IPC通信变得非常简单,类似本地方法调用的体验。开发者只需要关注业务逻辑,通信细节被框架封装起来。
三、实现细节
渲染进程
在渲染进程中,有两个主要的功能:
@ipc 装饰器
,用于发起对主进程方法的远程调用。
export function ipc(group: string) {
return (target: any, name: string, descriptor: PropertyDescriptor) => {
descriptor.value = function(...args: any[]) {
return ipcRenderer.invoke(group + ":" + name, ...args)
}
}
}
这个装饰器会拦截被装饰的方法,并在调用时使用ipcRenderer.invoke发起远程调用到主进程。
IPCProxy 类
,实现与主进程通信的接口,内部使用@ipc
装饰器发起远程调用。
export class UserQueryProxy implements IUserQuery {
@ipc("IUserQuery")
selectById(id: string) { ... }
}
这样一来,在渲染进程使用UserQueryProxy,调用selectById方法,实际会远程调用主进程的实现。
主进程
在主进程中,功能更加丰富:
@IpcMapping
装饰器,给类添加元数据,指定这个类所在的IPC通信group
。
@IpcMapping("IUserQuery")
export default class UserQueryIpc implements IUserQuery {
...
}
设计这个group的存在主要是为了防重,这个案例中使用了接口名称,当然也可以定义为其他值
- IPCManager 类,用于注册IPC监听和处理程序。
class IPCManager {
on(channel: string, callback: (...args: any[]) => void) { ... }
handle(channel: string, callback: (...args: any[]) => Promise<any>) { ... }
}
- 自动扫描机制,会扫描所有的
*.ipc.ts
文件,找到@IpcMapping
装饰过的类,并自动注册这个类的方法作为处理程序。
const ipcMappings = import.meta.globEager("../*.ipc.ts");
for (let ipcMappingsKey in ipcMappings) {
const IpcClass = ipcMappings[ipcMappingsKey].default;
const IpcMappingArgs = getDecorator(IpcClass, "IpcMapping");
Reflect.ownKeys(IpcClass.prototype)
.filter(key => key !== "constructor")
.forEach(key => {
useIPCManager.handle(`${IpcMappingArgs[0]}:${key}`, IpcClass.prototype[key]);
});
}
这样,UserQueryIpc
类的方法就自动成为了 IPC 通信
的处理程序,等待渲染进程的调用。
因为篇幅原因,代码未全部上传文章,如需这个ipc框架的全部代码,请在下方留言
总结
总之,这个IPC通信框架已经实现了基本功能,但要成为一个生产可用的框架,还需要不断完善和优化。这也是一个不断积累和提高的过程,需要在实践中不断总结和改进。
更多推荐
所有评论(0)