提交学习笔记专用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
3.6 KiB

  1. # birpc
  2. [![NPM version](https://img.shields.io/npm/v/birpc?color=a1b858&label=)](https://www.npmjs.com/package/birpc)
  3. Message-based two-way remote procedure call. Useful for WebSockets and Workers communication.
  4. ## Features
  5. - Intuitive - call remote functions just like locals, with Promise to get the response
  6. - TypeScript - safe function calls for arguments and returns
  7. - Protocol agonostic - WebSocket, MessageChannel, any protocols with messages communication would work!
  8. - Zero deps, ~0.5KB
  9. ## Examples
  10. ### Using WebSocket
  11. When using WebSocket, you need to pass your custom serializer and deserializer.
  12. #### Client
  13. ```ts
  14. import type { ServerFunctions } from './types'
  15. const ws = new WebSocket('ws://url')
  16. const clientFunctions: ClientFunctions = {
  17. hey(name: string) {
  18. return `Hey ${name} from client`
  19. }
  20. }
  21. const rpc = createBirpc<ServerFunctions>(
  22. clientFunctions,
  23. {
  24. post: data => ws.send(data),
  25. on: fn => ws.on('message', fn),
  26. // these are required when using WebSocket
  27. serialize: v => JSON.stringify(v),
  28. deserialize: v => JSON.parse(v),
  29. },
  30. )
  31. await rpc.hi('Client') // Hi Client from server
  32. ```
  33. #### Server
  34. ```ts
  35. import type { ClientFunctions } from './types'
  36. import { WebSocketServer } from 'ws'
  37. const serverFunctions: ServerFunctions = {
  38. hi(name: string) {
  39. return `Hi ${name} from server`
  40. }
  41. }
  42. const wss = new WebSocketServer()
  43. wss.on('connection', (ws) => {
  44. const rpc = createBirpc<ClientFunctions>(
  45. serverFunctions,
  46. {
  47. post: data => ws.send(data),
  48. on: fn => ws.on('message', fn),
  49. serialize: v => JSON.stringify(v),
  50. deserialize: v => JSON.parse(v),
  51. },
  52. )
  53. await rpc.hey('Server') // Hey Server from client
  54. })
  55. ```
  56. ### Circular References
  57. As `JSON.stringify` does not supporting circular references, we recommend using [`structured-clone-es`](https://github.com/antfu/structured-clone-es) as the serializer when you expect to have circular references.
  58. ```ts
  59. import { parse, stringify } from 'structured-clone-es'
  60. const rpc = createBirpc<ServerFunctions>(
  61. functions,
  62. {
  63. post: data => ws.send(data),
  64. on: fn => ws.on('message', fn),
  65. // use structured-clone-es as serializer
  66. serialize: v => stringify(v),
  67. deserialize: v => parse(v),
  68. },
  69. )
  70. ```
  71. ### Using MessageChannel
  72. [MessageChannel](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel) will automatically serialize the message and support circular references out-of-box.
  73. ```ts
  74. export const channel = new MessageChannel()
  75. ```
  76. #### Bob
  77. ``` ts
  78. import type { AliceFunctions } from './types'
  79. import { channel } from './channel'
  80. const Bob: BobFunctions = {
  81. hey(name: string) {
  82. return `Hey ${name}, I am Bob`
  83. }
  84. }
  85. const rpc = createBirpc<AliceFunctions>(
  86. Bob,
  87. {
  88. post: data => channel.port1.postMessage(data),
  89. on: fn => channel.port1.on('message', fn),
  90. },
  91. )
  92. await rpc.hi('Bob') // Hi Bob, I am Alice
  93. ```
  94. #### Alice
  95. ``` ts
  96. import type { BobFunctions } from './types'
  97. import { channel } from './channel'
  98. const Alice: AliceFunctions = {
  99. hi(name: string) {
  100. return `Hi ${name}, I am Alice`
  101. }
  102. }
  103. const rpc = createBirpc<BobFunctions>(
  104. Alice,
  105. {
  106. post: data => channel.port2.postMessage(data),
  107. on: fn => channel.port2.on('message', fn),
  108. },
  109. )
  110. await rpc.hey('Alice') // Hey Alice, I am Bob
  111. ```
  112. ### One-to-multiple Communication
  113. Refer to [./test/group.test.ts](./test/group.test.ts) as an example.
  114. ## Sponsors
  115. <p align="center">
  116. <a href="https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg">
  117. <img src='https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg'/>
  118. </a>
  119. </p>
  120. ## License
  121. [MIT](./LICENSE) License © 2021 [Anthony Fu](https://github.com/antfu)