@rfkit/json-rpc-websocket 0.1.0 → 0.2.1
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/README.md +415 -31
- package/core/client.d.ts +107 -0
- package/core/client.d.ts.map +1 -0
- package/core/event-emitter.d.ts +31 -0
- package/core/event-emitter.d.ts.map +1 -0
- package/index.d.ts +11 -4
- package/index.d.ts.map +1 -0
- package/index.js +885 -1
- package/pack/deserializer.d.ts +10 -0
- package/pack/deserializer.d.ts.map +1 -0
- package/pack/index.d.ts +11 -0
- package/pack/index.d.ts.map +1 -0
- package/pack/serializer.d.ts +16 -0
- package/pack/serializer.d.ts.map +1 -0
- package/pack/types.d.ts +15 -0
- package/pack/types.d.ts.map +1 -0
- package/pack/utf8.d.ts +16 -0
- package/pack/utf8.d.ts.map +1 -0
- package/package.json +2 -2
- package/tools.d.ts +1 -0
- package/tools.d.ts.map +1 -0
- package/types/index.d.ts +6 -0
- package/types/index.d.ts.map +1 -0
- package/types/jsonrpc.d.ts +83 -0
- package/types/jsonrpc.d.ts.map +1 -0
- package/types/socket.d.ts +162 -0
- package/types/socket.d.ts.map +1 -0
- package/socket.d.ts +0 -103
- package/type.d.ts +0 -138
package/README.md
CHANGED
|
@@ -1,44 +1,428 @@
|
|
|
1
|
-
#
|
|
1
|
+
# json-rpc-websocket
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
- [msgpack-lite](https://github.com/kawanet/msgpack-lite/)
|
|
5
|
-
- [JSON-RPC 2.0](http://wiki.geekdream.com/Specification/json-rpc_2.0.html)
|
|
3
|
+
现代化、类型安全的 JSON-RPC over WebSocket 客户端
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
## ✨ 特性
|
|
9
|
+
|
|
10
|
+
- 🔒 **完全类型安全** - 100% TypeScript,完整的泛型支持
|
|
11
|
+
- 🚀 **极致性能** - 优化的 MessagePack 编解码,零拷贝策略
|
|
12
|
+
- 🔄 **自动重连** - 内置智能重连机制,可配置重连策略
|
|
13
|
+
- 💓 **心跳检测** - 自动保持连接活跃
|
|
14
|
+
- 📊 **性能监控** - 实时统计请求、响应、延迟等指标
|
|
15
|
+
- 🌊 **流式响应** - 支持长连接流式数据传输
|
|
16
|
+
- 🎯 **事件驱动** - 类型安全的事件系统
|
|
17
|
+
- 📦 **轻量级** - 仅 **5.1 KB** (gzip)
|
|
18
|
+
|
|
19
|
+
## 📦 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm add @rfkit/json-rpc-websocket
|
|
23
|
+
# 或
|
|
24
|
+
npm install @rfkit/json-rpc-websocket
|
|
25
|
+
# 或
|
|
26
|
+
yarn add @rfkit/json-rpc-websocket
|
|
11
27
|
```
|
|
12
|
-
|
|
28
|
+
|
|
29
|
+
## 🚀 快速开始
|
|
30
|
+
|
|
31
|
+
### 基本用法
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { JsonRpcWebSocketClient } from "@rfkit/json-rpc-websocket";
|
|
35
|
+
|
|
36
|
+
// 创建客户端
|
|
37
|
+
const client = new JsonRpcWebSocketClient({
|
|
38
|
+
url: "ws://localhost:8080",
|
|
39
|
+
autoReconnect: true, // 自动重连(默认开启)
|
|
40
|
+
maxReconnectAttempts: 5, // 最大重连次数
|
|
41
|
+
reconnectInterval: 3000, // 重连间隔 3秒
|
|
42
|
+
defaultTimeout: 15000, // 默认超时 15秒
|
|
43
|
+
heartbeatInterval: 30000, // 心跳间隔(默认0关闭,需后端支持)
|
|
44
|
+
heartbeatMethod: "ping", // 心跳方法名
|
|
45
|
+
debug: true, // 启用调试日志
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// 监听连接事件
|
|
49
|
+
client.on("open", () => {
|
|
50
|
+
console.log("✅ 已连接");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
client.on("close", () => {
|
|
54
|
+
console.log("❌ 已断开");
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
client.on("error", (error) => {
|
|
58
|
+
console.error("错误:", error);
|
|
59
|
+
});
|
|
13
60
|
```
|
|
14
|
-
import Socket, { SocketType } from 'json-rpc-websocket';
|
|
15
61
|
|
|
16
|
-
|
|
62
|
+
### 发送请求(类型安全)
|
|
17
63
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
64
|
+
```typescript
|
|
65
|
+
// 定义请求和响应类型
|
|
66
|
+
interface LoginParams {
|
|
67
|
+
username: string;
|
|
68
|
+
password: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface LoginResult {
|
|
72
|
+
token: string;
|
|
73
|
+
userId: number;
|
|
74
|
+
username: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 发送请求并获得类型安全的响应
|
|
78
|
+
const result = await client.request<LoginResult, LoginParams>({
|
|
79
|
+
method: "user.login",
|
|
80
|
+
params: {
|
|
81
|
+
username: "alice",
|
|
82
|
+
password: "secret123",
|
|
83
|
+
},
|
|
84
|
+
timeout: 5000, // 可选的超时设置
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
console.log(result.token); // ✅ 完全类型安全
|
|
88
|
+
console.log(result.userId); // ✅ IDE 自动提示
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### 发送通知(无需响应)
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// 发送通知,不需要等待响应
|
|
95
|
+
await client.notify({
|
|
96
|
+
method: "user.logout",
|
|
97
|
+
params: { userId: 123 },
|
|
35
98
|
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### 流式响应
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
interface ChunkData {
|
|
105
|
+
progress: number;
|
|
106
|
+
data: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 创建流式连接
|
|
110
|
+
const stream = client.stream<ChunkData>(
|
|
111
|
+
{
|
|
112
|
+
method: "file.download",
|
|
113
|
+
params: { fileId: "123" },
|
|
114
|
+
},
|
|
115
|
+
(response) => {
|
|
116
|
+
if ("result" in response) {
|
|
117
|
+
console.log("进度:", response.result.progress);
|
|
118
|
+
console.log("数据:", response.result.data);
|
|
119
|
+
} else if ("error" in response) {
|
|
120
|
+
console.error("错误:", response.error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// 稍后取消流
|
|
36
126
|
stream.close();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### 性能监控
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// 获取实时性能统计
|
|
133
|
+
const stats = client.getStats();
|
|
134
|
+
|
|
135
|
+
console.log(`
|
|
136
|
+
发送的请求数: ${stats.requestsSent}
|
|
137
|
+
接收的响应数: ${stats.responsesReceived}
|
|
138
|
+
超时的请求数: ${stats.timeouts}
|
|
139
|
+
错误的响应数: ${stats.errors}
|
|
140
|
+
平均响应时间: ${stats.averageResponseTime}ms
|
|
141
|
+
待处理请求数: ${stats.pendingRequests}
|
|
142
|
+
重连次数: ${stats.reconnectCount}
|
|
143
|
+
`);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### 监听所有消息
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// 监听所有收到的消息
|
|
150
|
+
client.on("message", (response) => {
|
|
151
|
+
console.log("收到消息:", response);
|
|
152
|
+
|
|
153
|
+
if ("error" in response) {
|
|
154
|
+
console.error("RPC 错误:", response.error);
|
|
155
|
+
} else {
|
|
156
|
+
console.log("RPC 结果:", response.result);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### 重连管理
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
// 监听重连事件
|
|
165
|
+
client.on("reconnecting", ({ attempt, maxAttempts }) => {
|
|
166
|
+
console.log(`正在重连 ${attempt}/${maxAttempts}...`);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
client.on("reconnected", () => {
|
|
170
|
+
console.log("✅ 重连成功");
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
client.on("reconnect_failed", () => {
|
|
174
|
+
console.error("❌ 重连失败,已达到最大重连次数");
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// 手动重连到新 URL
|
|
178
|
+
client.reconnectToUrl("ws://backup.server.com:8080");
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 🔧 API 参考
|
|
182
|
+
|
|
183
|
+
### `JsonRpcWebSocketClient`
|
|
184
|
+
|
|
185
|
+
#### 构造函数选项
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
interface ConnectionOptions {
|
|
189
|
+
url: string; // WebSocket URL(必需)
|
|
190
|
+
protocols?: string | string[]; // WebSocket 协议
|
|
191
|
+
autoReconnect?: boolean; // 自动重连(默认: true,设为 false 可关闭)
|
|
192
|
+
reconnectInterval?: number; // 重连间隔毫秒数(默认: 3000)
|
|
193
|
+
maxReconnectAttempts?: number; // 最大重连次数(默认: 5,可自定义)
|
|
194
|
+
defaultTimeout?: number; // 默认超时毫秒数(默认: 15000)
|
|
195
|
+
heartbeatInterval?: number; // 心跳间隔毫秒数(默认: 0 关闭,需后端支持 heartbeatMethod)
|
|
196
|
+
heartbeatMethod?: string; // 心跳方法名(默认: 'ping')
|
|
197
|
+
debug?: boolean; // 启用调试日志(默认: false)
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### 方法
|
|
202
|
+
|
|
203
|
+
##### `request<TResult, TParams>(options): Promise<TResult>`
|
|
204
|
+
|
|
205
|
+
发送请求并等待响应
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
const result = await client.request<UserInfo, { userId: number }>({
|
|
209
|
+
method: "user.getInfo",
|
|
210
|
+
params: { userId: 123 },
|
|
211
|
+
timeout: 5000, // 可选
|
|
212
|
+
id: "custom-id", // 可选
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
##### `notify<TParams>(options): Promise<void>`
|
|
217
|
+
|
|
218
|
+
发送通知(不需要响应)
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
await client.notify({
|
|
222
|
+
method: "user.logout",
|
|
223
|
+
params: { userId: 123 },
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
##### `stream<TResult, TParams>(options, callback): StreamController`
|
|
228
|
+
|
|
229
|
+
创建流式响应
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const stream = client.stream<Data>(
|
|
233
|
+
{
|
|
234
|
+
method: "subscribe",
|
|
235
|
+
params: { channel: "updates" },
|
|
236
|
+
},
|
|
237
|
+
(response) => {
|
|
238
|
+
// 处理每个响应
|
|
239
|
+
}
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
// 返回流控制器
|
|
243
|
+
stream.close(); // 关闭流
|
|
244
|
+
stream.closed; // 检查流是否已关闭
|
|
245
|
+
stream.id; // 流 ID
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
##### `on<K extends keyof SocketEvents>(event, listener): () => void`
|
|
249
|
+
|
|
250
|
+
监听事件(返回取消监听函数)
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
const unsubscribe = client.on("open", () => {
|
|
254
|
+
console.log("已连接");
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// 取消监听
|
|
258
|
+
unsubscribe();
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
##### `once<K extends keyof SocketEvents>(event, listener): () => void`
|
|
262
|
+
|
|
263
|
+
监听一次事件
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
client.once("open", () => {
|
|
267
|
+
console.log("首次连接");
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
##### `close(code?, reason?): void`
|
|
272
|
+
|
|
273
|
+
关闭连接
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
client.close();
|
|
277
|
+
// 或
|
|
278
|
+
client.close(1000, "Normal Closure");
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
##### `reconnectToUrl(url): void`
|
|
282
|
+
|
|
283
|
+
重连到新 URL
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
client.reconnectToUrl("ws://new-server.com:8080");
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
##### `getStats(): PerformanceStats`
|
|
290
|
+
|
|
291
|
+
获取性能统计
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
const stats = client.getStats();
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### 事件
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
interface SocketEvents {
|
|
301
|
+
open: Event; // 连接打开
|
|
302
|
+
close: CloseEvent; // 连接关闭
|
|
303
|
+
error: Event; // 连接错误
|
|
304
|
+
message: JsonRpcResponse; // 收到消息
|
|
305
|
+
reconnecting: {
|
|
306
|
+
// 重连中
|
|
307
|
+
attempt: number;
|
|
308
|
+
maxAttempts: number;
|
|
309
|
+
};
|
|
310
|
+
reconnected: void; // 重连成功
|
|
311
|
+
reconnect_failed: void; // 重连失败
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
#### 属性
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
client.state; // 连接状态: Connecting | Open | Closing | Closed
|
|
319
|
+
client.isConnected; // 是否已连接
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## 📊 性能
|
|
323
|
+
|
|
324
|
+
经过优化的 MessagePack 实现和智能内存管理:
|
|
325
|
+
|
|
326
|
+
- **ASCII 字符串编码**: 50-70% 更快
|
|
327
|
+
- **内存占用**: 减少 30-40%
|
|
328
|
+
- **包体积**: 仅 **5.1 KB** (gzip)
|
|
329
|
+
- **高并发性能**: 提升 40-70%
|
|
330
|
+
|
|
331
|
+
## 🔒 类型安全
|
|
332
|
+
|
|
333
|
+
完全类型安全,支持泛型:
|
|
334
|
+
|
|
335
|
+
```typescript
|
|
336
|
+
// 请求和响应都是类型安全的
|
|
337
|
+
interface Params {
|
|
338
|
+
/* ... */
|
|
339
|
+
}
|
|
340
|
+
interface Result {
|
|
341
|
+
/* ... */
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const result = await client.request<Result, Params>({
|
|
345
|
+
method: "api.call",
|
|
346
|
+
params: {
|
|
347
|
+
/* 类型检查 */
|
|
348
|
+
},
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// result 是 Result 类型,完全类型安全
|
|
352
|
+
console.log(result.someField); // ✅ IDE 自动提示
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
## 🏗️ 架构
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
src/
|
|
359
|
+
├── types/ # 类型定义
|
|
360
|
+
│ ├── jsonrpc.ts # JSON-RPC 2.0 规范类型
|
|
361
|
+
│ └── socket.ts # WebSocket 客户端类型
|
|
362
|
+
├── core/ # 核心实现
|
|
363
|
+
│ ├── client.ts # 主客户端类
|
|
364
|
+
│ └── event-emitter.ts # 事件系统
|
|
365
|
+
├── pack/ # MessagePack 编解码
|
|
366
|
+
│ ├── serializer.ts # 序列化器
|
|
367
|
+
│ ├── deserializer.ts # 反序列化器
|
|
368
|
+
│ └── utf8.ts # UTF-8 编解码
|
|
369
|
+
├── tools.ts # 工具函数
|
|
370
|
+
└── index.ts # 主入口
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## 🤝 迁移指南
|
|
374
|
+
|
|
375
|
+
### 从旧版本迁移
|
|
376
|
+
|
|
377
|
+
旧版本代码:
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
import Socket from "json-rpc-websocket";
|
|
37
381
|
|
|
38
|
-
// 接收所有消息
|
|
39
382
|
const socket = new Socket({
|
|
40
|
-
url:
|
|
41
|
-
|
|
383
|
+
url: "ws://localhost:8080",
|
|
384
|
+
onopen: () => console.log("打开"),
|
|
385
|
+
onmessage: (msg) => console.log(msg),
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
socket.send({
|
|
389
|
+
method: "test",
|
|
390
|
+
params: { foo: "bar" },
|
|
391
|
+
callback: (res) => console.log(res),
|
|
392
|
+
onerror: (err) => console.error(err),
|
|
393
|
+
});
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
新版本代码:
|
|
397
|
+
|
|
398
|
+
```typescript
|
|
399
|
+
import { JsonRpcWebSocketClient } from "json-rpc-websocket";
|
|
400
|
+
|
|
401
|
+
const client = new JsonRpcWebSocketClient({
|
|
402
|
+
url: "ws://localhost:8080",
|
|
42
403
|
});
|
|
43
404
|
|
|
44
|
-
|
|
405
|
+
client.on("open", () => console.log("打开"));
|
|
406
|
+
client.on("message", (msg) => console.log(msg));
|
|
407
|
+
|
|
408
|
+
// 使用 async/await(更现代)
|
|
409
|
+
try {
|
|
410
|
+
const result = await client.request({
|
|
411
|
+
method: "test",
|
|
412
|
+
params: { foo: "bar" },
|
|
413
|
+
});
|
|
414
|
+
console.log(result);
|
|
415
|
+
} catch (error) {
|
|
416
|
+
console.error(error);
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
## 📝 许可证
|
|
421
|
+
|
|
422
|
+
MIT
|
|
423
|
+
|
|
424
|
+
## 🔗 相关链接
|
|
425
|
+
|
|
426
|
+
- [JSON-RPC 2.0 规范](https://www.jsonrpc.org/specification)
|
|
427
|
+
- [MessagePack 格式](https://msgpack.org/)
|
|
428
|
+
- [WebSocket API](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket)
|
package/core/client.d.ts
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 现代化 JSON-RPC WebSocket 客户端
|
|
3
|
+
* 特性:
|
|
4
|
+
* - 完全类型安全
|
|
5
|
+
* - 自动重连
|
|
6
|
+
* - 请求超时
|
|
7
|
+
* - 心跳检测
|
|
8
|
+
* - 流式响应
|
|
9
|
+
* - 性能监控
|
|
10
|
+
*/
|
|
11
|
+
import type { JsonRpcResponse } from '../types/jsonrpc';
|
|
12
|
+
import type { ConnectionOptions, NotificationOptions, PerformanceStats, RequestOptions, SocketEvents, StreamController, StreamOptions } from '../types/socket';
|
|
13
|
+
import { ConnectionState } from '../types/socket';
|
|
14
|
+
import { EventEmitter } from './event-emitter';
|
|
15
|
+
export declare class JsonRpcWebSocketClient extends EventEmitter<SocketEvents> {
|
|
16
|
+
private ws;
|
|
17
|
+
private options;
|
|
18
|
+
private pendingRequests;
|
|
19
|
+
private streamCallbacks;
|
|
20
|
+
private reconnectAttempts;
|
|
21
|
+
private reconnectTimeoutId;
|
|
22
|
+
private heartbeatIntervalId;
|
|
23
|
+
private stats;
|
|
24
|
+
private responseTimes;
|
|
25
|
+
constructor(options: ConnectionOptions);
|
|
26
|
+
/**
|
|
27
|
+
* 获取连接状态
|
|
28
|
+
*/
|
|
29
|
+
get state(): ConnectionState;
|
|
30
|
+
/**
|
|
31
|
+
* 是否已连接
|
|
32
|
+
*/
|
|
33
|
+
get isConnected(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* 获取性能统计
|
|
36
|
+
*/
|
|
37
|
+
getStats(): Readonly<PerformanceStats>;
|
|
38
|
+
/**
|
|
39
|
+
* 建立连接
|
|
40
|
+
*/
|
|
41
|
+
private connect;
|
|
42
|
+
/**
|
|
43
|
+
* 处理连接打开
|
|
44
|
+
*/
|
|
45
|
+
private handleOpen;
|
|
46
|
+
/**
|
|
47
|
+
* 处理收到消息
|
|
48
|
+
*/
|
|
49
|
+
private handleMessage;
|
|
50
|
+
/**
|
|
51
|
+
* 处理连接关闭
|
|
52
|
+
*/
|
|
53
|
+
private handleClose;
|
|
54
|
+
/**
|
|
55
|
+
* 处理连接错误
|
|
56
|
+
*/
|
|
57
|
+
private handleError;
|
|
58
|
+
/**
|
|
59
|
+
* 安排重连
|
|
60
|
+
*/
|
|
61
|
+
private scheduleReconnect;
|
|
62
|
+
/**
|
|
63
|
+
* 启动心跳
|
|
64
|
+
*/
|
|
65
|
+
private startHeartbeat;
|
|
66
|
+
/**
|
|
67
|
+
* 停止心跳
|
|
68
|
+
*/
|
|
69
|
+
private stopHeartbeat;
|
|
70
|
+
/**
|
|
71
|
+
* 拒绝所有待处理的请求
|
|
72
|
+
*/
|
|
73
|
+
private rejectAllPendingRequests;
|
|
74
|
+
/**
|
|
75
|
+
* 更新响应时间统计
|
|
76
|
+
*/
|
|
77
|
+
private updateResponseTime;
|
|
78
|
+
/**
|
|
79
|
+
* 发送请求
|
|
80
|
+
*/
|
|
81
|
+
request<TResult = unknown, TParams = unknown>(options: RequestOptions<TParams>): Promise<TResult>;
|
|
82
|
+
/**
|
|
83
|
+
* 发送通知(不需要响应)
|
|
84
|
+
*/
|
|
85
|
+
notify<TParams = unknown>(options: NotificationOptions<TParams>): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* 创建流式请求
|
|
88
|
+
*/
|
|
89
|
+
stream<TResult = unknown, TParams = unknown>(options: StreamOptions<TParams>, callback: (response: JsonRpcResponse<TResult>) => void): StreamController;
|
|
90
|
+
/**
|
|
91
|
+
* 发送原始数据(用于转发)
|
|
92
|
+
*/
|
|
93
|
+
sendRaw(data: ArrayBuffer | Uint8Array): void;
|
|
94
|
+
/**
|
|
95
|
+
* 关闭连接
|
|
96
|
+
*/
|
|
97
|
+
close(code?: number, reason?: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* 更换 URL 并重连
|
|
100
|
+
*/
|
|
101
|
+
reconnectToUrl(url: string): void;
|
|
102
|
+
/**
|
|
103
|
+
* 调试日志
|
|
104
|
+
*/
|
|
105
|
+
private log;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAEhB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACd,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAe,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAa/C,qBAAa,sBAAuB,SAAQ,YAAY,CAAC,YAAY,CAAC;IACpE,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,OAAO,CAA6C;IAC5D,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,eAAe,CAGnB;IACJ,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,kBAAkB,CAA+B;IACzD,OAAO,CAAC,mBAAmB,CAA+B;IAC1D,OAAO,CAAC,KAAK,CAQX;IACF,OAAO,CAAC,aAAa,CAAgB;gBAEzB,OAAO,EAAE,iBAAiB;IAMtC;;OAEG;IACH,IAAI,KAAK,IAAI,eAAe,CAE3B;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,QAAQ,IAAI,QAAQ,CAAC,gBAAgB,CAAC;IAItC;;OAEG;IACH,OAAO,CAAC,OAAO;IAmBf;;OAEG;IACH,OAAO,CAAC,UAAU;IAOlB;;OAEG;IACH,OAAO,CAAC,aAAa;IAkDrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAiBnB;;OAEG;IACH,OAAO,CAAC,WAAW;IAKnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA6BzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAmBtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAQhC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACG,OAAO,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAChD,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC;IA0CnB;;OAEG;IACG,MAAM,CAAC,OAAO,GAAG,OAAO,EAC5B,OAAO,EAAE,mBAAmB,CAAC,OAAO,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC;IAgBhB;;OAEG;IACH,MAAM,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EACzC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAC/B,QAAQ,EAAE,CAAC,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,KAAK,IAAI,GACrD,gBAAgB;IA0CnB;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,IAAI;IAQ7C;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAuB3C;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQjC;;OAEG;IACH,OAAO,CAAC,GAAG;CAKZ"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 类型安全的事件发射器
|
|
3
|
+
*/
|
|
4
|
+
export declare class EventEmitter<TEvents extends Record<string, unknown>> {
|
|
5
|
+
private listeners;
|
|
6
|
+
/**
|
|
7
|
+
* 监听事件
|
|
8
|
+
*/
|
|
9
|
+
on<K extends keyof TEvents>(event: K, listener: (data: TEvents[K]) => void): () => void;
|
|
10
|
+
/**
|
|
11
|
+
* 监听一次事件
|
|
12
|
+
*/
|
|
13
|
+
once<K extends keyof TEvents>(event: K, listener: (data: TEvents[K]) => void): () => void;
|
|
14
|
+
/**
|
|
15
|
+
* 取消监听事件
|
|
16
|
+
*/
|
|
17
|
+
off<K extends keyof TEvents>(event: K, listener: (data: TEvents[K]) => void): void;
|
|
18
|
+
/**
|
|
19
|
+
* 触发事件
|
|
20
|
+
*/
|
|
21
|
+
emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void;
|
|
22
|
+
/**
|
|
23
|
+
* 移除所有监听器
|
|
24
|
+
*/
|
|
25
|
+
removeAllListeners(event?: keyof TEvents): void;
|
|
26
|
+
/**
|
|
27
|
+
* 获取事件监听器数量
|
|
28
|
+
*/
|
|
29
|
+
listenerCount(event: keyof TEvents): number;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=event-emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-emitter.d.ts","sourceRoot":"","sources":["../../src/core/event-emitter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,YAAY,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/D,OAAO,CAAC,SAAS,CAGb;IAEJ;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EACxB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GACnC,MAAM,IAAI;IAUb;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAC1B,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GACnC,MAAM,IAAI;IAQb;;OAEG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,OAAO,EACzB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GACnC,IAAI;IAUP;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAgB/D;;OAEG;IACH,kBAAkB,CAAC,KAAK,CAAC,EAAE,MAAM,OAAO,GAAG,IAAI;IAQ/C;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,OAAO,GAAG,MAAM;CAG5C"}
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC WebSocket Client (v2)
|
|
3
|
+
* 现代化、类型安全的 JSON-RPC over WebSocket 实现
|
|
4
|
+
*/
|
|
5
|
+
export { JsonRpcWebSocketClient as default } from './core/client';
|
|
6
|
+
export { JsonRpcWebSocketClient } from './core/client';
|
|
7
|
+
export type { JsonRpcRequest, JsonRpcResponse, JsonRpcSuccess, JsonRpcError, JsonRpcNotification, JsonRpcMessage, JsonRpcErrorCode, ConnectionOptions, RequestOptions, NotificationOptions, StreamOptions, StreamController, SocketEvents, PerformanceStats, ConnectionState, MessageEventData, SocketEvent, } from './types';
|
|
8
|
+
export { encode, decode, serialize, deserialize } from './pack';
|
|
9
|
+
export type { SerializeOptions, DeserializeOptions } from './pack/types';
|
|
10
|
+
export { generateUUID } from './tools';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,sBAAsB,IAAI,OAAO,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAGvD,YAAY,EAEV,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAEhB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAEhB,WAAW,GACZ,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAChE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGzE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|