一个基于 JSON-RPC 规范用于处理 window && iframe && worker 通讯的工具库
原生的window && iframe && worker communication的调用方式可以处理简单的事件通信,但针对复杂场景下跨页面(进程)通信需要一个简单的有效的处理方式,如果可以封装成异步函数调用方式,则会优雅很多,如下(官网):
安装
yarn add rpc-shooter
# or
npm i rpc-shooter -S
使用
使用 RPCMessageEvent 模块可以涵盖下列模块的消息通信:
iframe
- main.ts
// main.ts
import { RPCMessageEvent, RPC } from 'rpc-shooter';
(async function () {
const iframe = document.querySelector('iframe')!;
const rpc = new RPC({
event: new RPCMessageEvent({
currentEndpoint: window,
targetEndpoint: iframe.contentWindow!,
config: { targetOrigin: '*' },
}),
// 初始化时注册处理函数
methods: {
'Main.max': (a: number, b: number) => Math.max(a, b),
},
});
// 动态注册处理函数
rpc.registerMethod('Main.min', (a: number, b: number) => {
return Promise.resolve(Math.min(a, b));
});
// 检查链接,配置超时时间
await rpc.connect(2000);
// 调用 iframe 服务中的注册方法
const randomValue = await rpc.invoke('Child.random', null, { isNotify: false, timeout: 2000 });
console.log(`Main invoke Child.random result: ${randomValue}`);
})();
- child.ts
// child.ts
import { RPCMessageEvent, RPC } from 'rpc-shooter';
(async function () {
const rpc = new RPC({
event: new RPCMessageEvent({
currentEndpoint: window,
targetEndpoint: window.top,
}),
});
rpc.registerMethod('Child.random', () => Math.random());
await rpc.connect(2000);
const max = await rpc.invoke('Main.max', [1, 2]);
const min = await rpc.invoke('Main.min', [1, 2]);
console.log({ max, min });
})();
Web Worker
- main.ts
// main.ts
import { RPCMessageEvent, RPC } from 'rpc-shooter';
(async function () {
const worker = new Worker('./slef.worker.ts');
const rpc = new RPC({
event: new RPCMessageEvent({
currentEndpoint: worker,
targetEndpoint: worker,
}),
});
rpc.registerMethod('Main.max', (a: number, b: number) => {
return Promise.resolve(Math.max(a, b));
});
await rpc.connect(2000);
await rpc.invoke('Child.random', null);
})();
- child.ts
// child.ts
import { RPCMessageEvent, RPC } from 'rpc-shooter';
(async function () {
const ctx: Worker = self as any;
const rpc = new RPC({
event: new RPCMessageEvent({
currentEndpoint: ctx,
targetEndpoint: ctx,
}),
});
rpc.registerMethod('Child.random', () => Math.random());
await rpc.connect(2000);
await rpc.invoke('Main.max', [1, 2]);
})();