js-rpc2 2.4.2 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/doc/websocket.md CHANGED
@@ -149,7 +149,7 @@ example()
149
149
 
150
150
  #### createRpcServerWebSocket
151
151
 
152
- 创建 WebSocket RPC 服务器。
152
+ 创建 WebSocket RPC 服务器,自动绑定 connection 事件。
153
153
 
154
154
  ```js
155
155
  /**
@@ -157,7 +157,7 @@ example()
157
157
  * path: string;
158
158
  * wss: WebSocketServer;
159
159
  * rpcKey:string;
160
- * extension: {asyncLocalStorage:AsyncLocalStorage<IncomingMessage>;};
160
+ * extension: {asyncLocalStorage:AsyncLocalStorage<{ws:WebSocket;request:IncomingMessage;}>;};
161
161
  * logger?:(msg:string)=>void;
162
162
  * }} param
163
163
  */
@@ -168,9 +168,55 @@ export function createRpcServerWebSocket(param)
168
168
  - `path`: RPC 服务的路径,用于区分不同的服务
169
169
  - `wss`: WebSocketServer 实例
170
170
  - `rpcKey`: 可选的安全密钥,用于验证客户端连接
171
- - `extension`: 包含可远程调用函数的对象
171
+ - `extension`: 包含可远程调用函数的对象,可提供 `asyncLocalStorage` 用于存储当前连接上下文(包含 `ws` 和 `request`)
172
172
  - `logger`: 可选的日志函数
173
173
 
174
+ #### createRpcServerWebSocketOnConnection
175
+
176
+ 创建 WebSocket RPC 连接处理函数,返回一个可用于 `wss.on('connection', handler)` 的处理函数。适用于需要自定义连接绑定逻辑的场景。
177
+
178
+ ```js
179
+ /**
180
+ * @param {{
181
+ * path: string;
182
+ * wss: WebSocketServer;
183
+ * rpcKey:string;
184
+ * extension: {asyncLocalStorage:AsyncLocalStorage<{ws:WebSocket;request:IncomingMessage;}>;};
185
+ * logger?:(msg:string)=>void;
186
+ * }} param
187
+ * @returns {(ws: WebSocket, request: IncomingMessage) => void}
188
+ */
189
+ export function createRpcServerWebSocketOnConnection(param)
190
+ ```
191
+
192
+ 使用示例:
193
+ ```js
194
+ import { createServer } from 'http'
195
+ import { WebSocketServer } from 'ws'
196
+ import { createRpcServerWebSocketOnConnection } from 'js-rpc2/src/server.js'
197
+
198
+ const server = createServer()
199
+ const wss = new WebSocketServer({ server })
200
+
201
+ // 获取连接处理函数
202
+ const onConnection = createRpcServerWebSocketOnConnection({
203
+ path: '/rpc',
204
+ rpcKey: 'secret-key',
205
+ extension: { /* your API methods */ }
206
+ })
207
+
208
+ // 自定义绑定方式
209
+ wss.on('connection', (ws, request) => {
210
+ // 可以在这里添加自定义逻辑
211
+ console.log('New connection from:', request.socket.remoteAddress)
212
+
213
+ // 调用 RPC 连接处理
214
+ onConnection(ws, request)
215
+ })
216
+
217
+ server.listen(9000)
218
+ ```
219
+
174
220
  ### 客户端 API
175
221
 
176
222
  #### createRpcClientWebSocket
package/jsconfig.json CHANGED
@@ -1,29 +1,40 @@
1
1
  {
2
- "compilerOptions": {
3
- "moduleResolution": "nodenext",
4
- "target": "ESNext",
5
- "module": "NodeNext",
6
- "types": ["node"],
7
- "isolatedModules": true,
8
- "resolveJsonModule": true,
9
- /**
2
+ "compilerOptions": {
3
+ "moduleResolution": "nodenext",
4
+ "target": "ESNext",
5
+ "module": "NodeNext",
6
+ "types": [
7
+ "node"
8
+ ],
9
+ "isolatedModules": true,
10
+ "resolveJsonModule": true,
11
+ /**
10
12
  * To have warnings / errors of the Svelte compiler at the
11
13
  * correct position, enable source maps by default.
12
14
  */
13
- "sourceMap": true,
14
- "esModuleInterop": true,
15
- "skipLibCheck": true,
16
- "forceConsistentCasingInFileNames": true,
17
- "baseUrl": ".",
18
- /**
15
+ "sourceMap": true,
16
+ "esModuleInterop": true,
17
+ "skipLibCheck": true,
18
+ "forceConsistentCasingInFileNames": true,
19
+ /**
19
20
  * Typecheck JS in `.svelte` and `.js` files by default.
20
21
  * Disable this if you'd like to use dynamic types.
21
22
  */
22
- "checkJs": true
23
- },
24
- /**
23
+ "checkJs": true,
24
+ "strict": true,
25
+ "strictNullChecks": false,
26
+ "noImplicitAny": false,
27
+ "useUnknownInCatchVariables": false,
28
+ },
29
+ /**
25
30
  * Use global.d.ts instead of compilerOptions.types
26
31
  * to avoid limiting type declarations.
27
32
  */
28
- "include": ["src/**/*.d.ts", "src/**/*.js", "bin/**/*.js", "src/**/*.svelte", "*.js"]
29
- }
33
+ "include": [
34
+ "src/**/*.d.ts",
35
+ "src/**/*.js",
36
+ "bin/**/*.js",
37
+ "src/**/*.svelte",
38
+ "*.js"
39
+ ]
40
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-rpc2",
3
- "version": "2.4.2",
3
+ "version": "2.5.0",
4
4
  "description": "js web websocket http rpc",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/src/lib.js CHANGED
@@ -660,7 +660,7 @@ export function createRpcClientHelper(param) {
660
660
  * url:string;
661
661
  * rpcKey:string;
662
662
  * signal:AbortSignal;
663
- * intercept?:(e:Event)=>void;
663
+ * intercept?:(e:CloseEvent)=>void;
664
664
  * }} param
665
665
  */
666
666
  export function createRpcClientWebSocket(param) {
package/src/server.js CHANGED
@@ -4,7 +4,7 @@ import { AsyncLocalStorage } from "node:async_hooks"
4
4
 
5
5
  /**
6
6
  * @import { IncomingMessage } from "node:http"
7
- * @import {WebSocketServer} from 'ws'
7
+ * @import {WebSocket, WebSocketServer} from 'ws'
8
8
  */
9
9
 
10
10
  export { createRpcServerHelper }
@@ -14,19 +14,38 @@ export { createRpcServerHelper }
14
14
  */
15
15
 
16
16
  /**
17
- * @template T
18
17
  * @param {{
19
18
  * path: string;
20
19
  * wss: WebSocketServer;
21
20
  * rpcKey:string;
22
- * extension: {asyncLocalStorage:AsyncLocalStorage<IncomingMessage>;};
21
+ * extension: {asyncLocalStorage:AsyncLocalStorage<{ws:WebSocket;request:IncomingMessage;}>;};
23
22
  * logger?:(msg:string)=>void;
24
23
  * }} param
25
24
  */
26
25
  export function createRpcServerWebSocket(param) {
27
26
  let asyncLocalStorage = param.extension.asyncLocalStorage
28
27
  if (!asyncLocalStorage) { asyncLocalStorage = new AsyncLocalStorage() }
29
- param.wss.on('connection', (ws, request) => {
28
+ const onconnection = createRpcServerWebSocketOnConnection(param)
29
+ param.wss.on('connection', onconnection)
30
+ }
31
+
32
+ /**
33
+ * @param {{
34
+ * path: string;
35
+ * wss: WebSocketServer;
36
+ * rpcKey:string;
37
+ * extension: {asyncLocalStorage:AsyncLocalStorage<{ws:WebSocket;request:IncomingMessage;}>;};
38
+ * logger?:(msg:string)=>void;
39
+ * }} param
40
+ */
41
+ export function createRpcServerWebSocketOnConnection(param) {
42
+ let asyncLocalStorage = param.extension.asyncLocalStorage
43
+ if (!asyncLocalStorage) { asyncLocalStorage = new AsyncLocalStorage() }
44
+ /**
45
+ * @param {WebSocket} ws
46
+ * @param {IncomingMessage} request
47
+ */
48
+ return function (ws, request) {
30
49
  let url = request.url
31
50
  if (url != param.path) {
32
51
  return
@@ -46,7 +65,7 @@ export function createRpcServerWebSocket(param) {
46
65
  if (writer.desiredSize <= 0) {
47
66
  ws.pause()
48
67
  }
49
- asyncLocalStorage.enterWith(request)
68
+ asyncLocalStorage.enterWith({ ws, request })
50
69
  await writer.write(buffer)
51
70
  ws.resume()
52
71
  })
@@ -56,7 +75,7 @@ export function createRpcServerWebSocket(param) {
56
75
  ws.on('error', (error) => {
57
76
  console.error('createRpcServerWebSocket connection ws error', error)
58
77
  })
59
- })
78
+ }
60
79
  }
61
80
 
62
81
  /**