{"id":13680812,"url":"https://github.com/LZQCN/web-message-rpc","last_synced_at":"2025-04-30T00:30:57.768Z","repository":{"id":189567051,"uuid":"680742320","full_name":"LZQCN/web-message-rpc","owner":"LZQCN","description":"A class for implementing Remote Procedure Call (RPC) between web applications, providing an easy-to-use interface with ES6 Proxy-based method invocation.","archived":false,"fork":false,"pushed_at":"2024-04-08T18:37:37.000Z","size":21,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-21T03:19:28.898Z","etag":null,"topics":["class","proxy","rpc","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LZQCN.png","metadata":{"files":{"readme":"README.cn.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-20T08:50:22.000Z","updated_at":"2024-04-24T09:14:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"a0cbf591-927d-4480-ab89-a3919a4926ae","html_url":"https://github.com/LZQCN/web-message-rpc","commit_stats":null,"previous_names":["lzqcn/web-message-rpc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LZQCN%2Fweb-message-rpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LZQCN%2Fweb-message-rpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LZQCN%2Fweb-message-rpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LZQCN%2Fweb-message-rpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LZQCN","download_url":"https://codeload.github.com/LZQCN/web-message-rpc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251607420,"owners_count":21616755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class","proxy","rpc","typescript"],"created_at":"2024-08-02T13:01:22.289Z","updated_at":"2025-04-30T00:30:52.936Z","avatar_url":"https://github.com/LZQCN.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"[English](./README.md) | 简体中文\r\n\r\n# Web Message RPC\r\n\r\nWeb Message RPC 是一个用于实现 Web 应用间远程过程调用（RPC）的类。\r\n\r\n## 安装\r\n\r\n使用 npm 安装该类：\r\n\r\n```\r\nnpm install web-message-rpc\r\n```\r\n\r\n## 使用方法\r\n\r\n### 导入 `WebMessageRPC` 类：\r\n\r\n```typescript\r\nimport { WebMessageRPC, Adapter } from \"web-message-rpc\";\r\n```\r\n\r\n### 在一端注册方法，并在另一端调用方法：\r\n\r\n- 在 A 端通过 WebMessageRPC 实例注册方法：\r\n\r\n```typescript\r\n// 使用适配器对象创建一个 WebMessageRPC 实例：\r\nconst rpc = new WebMessageRPC(adapter);\r\n\r\n// 将方法注册到 WebMessageRPC 实例\r\nrpc.register({\r\n  add(a: number, b: number) {\r\n    return a + b;\r\n  },\r\n  subtract(a: number, b: number) {\r\n    return a - b;\r\n  },\r\n});\r\n```\r\n\r\n- 现在，你可以在 B 端通过 WebMessageRPC 实例进行远程方法调用，如下所示：\r\n\r\n```typescript\r\n// 使用适配器对象创建一个 WebMessageRPC 实例：\r\nconst rpc = new WebMessageRPC(adapter);\r\n\r\nasync function main() {\r\n  // 通过 rpc.callProxy 调用 A 端提供的方法，就像调用普通的函数一样。\r\n  const result = await rpc.callProxy.add(1, 2);\r\n  console.log(result); // 输出: 3\r\n}\r\n\r\nmain();\r\n```\r\n\r\n### 使用命名空间：\r\n\r\n- 在 A 端，注册方法，并指定命名空间：\r\n\r\n```typescript\r\n// 使用适配器对象创建一个 WebMessageRPC 实例：\r\nconst rpc = new WebMessageRPC(adapter);\r\n\r\n// 在注册方法时，第一个参数填写命名空间\r\nrpc.register(\"myNamespace\", {\r\n  add(a: number, b: number) {\r\n    return a + b;\r\n  },\r\n  subtract(a: number, b: number) {\r\n    return a - b;\r\n  },\r\n});\r\n```\r\n\r\n- 在 B 端，使用指定的命名空间：\r\n\r\n```typescript\r\n// 使用适配器对象创建一个 WebMessageRPC 实例：\r\nconst rpc = new WebMessageRPC(adapter);\r\n\r\n// 指定命名空间获得代理对象\r\nconst myNamespace = rpc.use(\"myNamespace\");\r\n\r\nasync function main() {\r\n  // 通过命名空间可以更简洁地调用方法\r\n  const result = await myNamespace.add(1, 2);\r\n  console.log(result); // 输出: 3\r\n}\r\n\r\nmain();\r\n```\r\n\r\n### 创建一个 `Adapter` 适配器对象，用于发送和接收消息。适配器对象需要实现以下接口：\r\n\r\n```typescript\r\ninterface Adapter {\r\n  addEventListener(callback: Function): void;\r\n  removeEventListener(callback: Function): void;\r\n  postMessage(payload: any): void;\r\n}\r\n```\r\n\r\nWebSocket 适配器例子：\r\n\r\n- 服务端\r\n\r\n```typescript\r\nlet handler;\r\nconst adapter: Adapter = {\r\n  addEventListener(callback) {\r\n    handler = (str) =\u003e callback(JSON.parse(str));\r\n    ws.on(\"message\", handler);\r\n  },\r\n  removeEventListener(callback) {\r\n    ws.off(\"message\", handler);\r\n  },\r\n  postMessage(payload) {\r\n    ws.send(JSON.stringify(payload));\r\n  },\r\n};\r\n```\r\n\r\n- 客户端\r\n\r\n```typescript\r\nlet handler;\r\nconst adapter: Adapter = {\r\n  addEventListener(callback) {\r\n    handler = (str) =\u003e callback(JSON.parse(str));\r\n    ws.addEventListener(\"message\", handler);\r\n  },\r\n  removeEventListener(callback) {\r\n    ws.removeEventListener(\"message\", handler);\r\n  },\r\n  postMessage(payload) {\r\n    ws.send(JSON.stringify(payload));\r\n  },\r\n};\r\n```\r\n\r\n\u003e 注意，在使用 WebSocket 通信时，您需要自行实现数据的序列化与反序列化，`JSON.stringify()` 和 `JSON.parse()` 只是最简单一种方式。\r\n\r\niframe 适配器例子：\r\n\r\n- 父页面：\r\n\r\n```typescript\r\nlet handler;\r\nconst adapter: Adapter = {\r\n  addEventListener(callback) {\r\n    handler = (e) =\u003e callback(e.data);\r\n    window.addEventListener(\"message\", handler);\r\n  },\r\n  removeEventListener(callback) {\r\n    window.removeEventListener(\"message\", handler);\r\n  },\r\n  postMessage(payload) {\r\n    iframe.contentWindow.postMessage(payload);\r\n  },\r\n};\r\n```\r\n\r\n- 子页面：\r\n\r\n```typescript\r\nlet handler;\r\nconst adapter: Adapter = {\r\n  addEventListener(callback) {\r\n    handler = (e) =\u003e callback(e.data);\r\n    window.addEventListener(\"message\", handler);\r\n  },\r\n  removeEventListener(callback) {\r\n    window.removeEventListener(\"message\", handler);\r\n  },\r\n  postMessage(payload) {\r\n    window.parent.postMessage(payload);\r\n  },\r\n};\r\n```\r\n\r\n## 方法\r\n\r\n### register\r\n\r\n将一个方法集合注册到调用记录中。\r\n\r\n```typescript\r\nregister(methods: {[methodName: string]: (...args: any[]) =\u003e any})\r\nregister(namespace: string, methods: {[methodName: string]: (...args: any[]) =\u003e any})\r\n```\r\n\r\n- `methods`：要注册的方法集合对象，包含方法名和对应的函数。\r\n- `namespace`：可选参数，用于命名空间。\r\n\r\n### deregister\r\n\r\n从调用记录中取消注册一个方法或方法集合。\r\n\r\n```typescript\r\nderegister(methods: {[methodName: string]: (...args: any[]) =\u003e any})\r\nderegister(namespace: string, methods: {[methodName: string]: (...args: any[]) =\u003e any})\r\n```\r\n\r\n- `methods`：要取消注册的方法集合对象，包含方法名和对应的函数。\r\n- `namespace`：可选参数，用于命名空间。\r\n\r\n### use\r\n\r\n创建一个命名空间的代理对象，用于调用该命名空间下的方法。\r\n\r\n```typescript\r\nuse(namespace: string): {[methodName: string]: (...args: any[]) =\u003e any};\r\n```\r\n\r\n- `namespace`：命名空间。\r\n\r\n### destroy\r\n\r\n销毁 WebMessageRPC 实例，清空回调函数和 Promise 对象。\r\n\r\n## 贡献\r\n\r\n欢迎提供改进建议和报告问题。\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLZQCN%2Fweb-message-rpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLZQCN%2Fweb-message-rpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLZQCN%2Fweb-message-rpc/lists"}