sx-peerjs-http-util 1.0.6 → 1.2.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/README.md CHANGED
@@ -1,319 +1,64 @@
1
1
  # sx-peerjs-http-util
2
2
 
3
- 一个浏览器端库,将 PeerJS 封装成简单易用的类似 HTTP 的 API,并支持语音/视频通话。
3
+ PeerJS 封装成类似 HTTP 的 API,支持语音/视频通话和自动路由。
4
4
 
5
- ## 特性
5
+ ## 在线 Demo
6
6
 
7
- - 简单的请求-响应 API,类似 HTTP
8
- - 基于 PeerJS (WebRTC) 实现 P2P 通信
9
- - **语音/视频通话**:支持一对一语音和视频通话
10
- - TypeScript 支持
11
- - 完整的 E2E 测试
12
- - **支持 NPM 和 CDN 两种引入方式**
13
- - **自动断线重连**
14
- - **可指定或自动生成 Peer ID**
7
+ | Demo | 说明 |
8
+ |------|------|
9
+ | [文字传输](https://anarckk.github.io/sx-peerjs-http-util/demos/text-chat/index.html) | P2P 即时聊天 |
10
+ | [文件传输](https://anarckk.github.io/sx-peerjs-http-util/demos/file-transfer/index.html) | 点对点文件传输 |
11
+ | [语音通话](https://anarckk.github.io/sx-peerjs-http-util/demos/voice-call/index.html) | 一对一语音通话 |
12
+ | [视频通话](https://anarckk.github.io/sx-peerjs-http-util/demos/video-call/index.html) | 一对一视频通话 |
15
13
 
16
14
  ## 安装
17
15
 
18
- ### NPM 方式
19
-
16
+ **NPM:**
20
17
  ```bash
21
18
  npm install sx-peerjs-http-util peerjs
22
19
  ```
23
20
 
24
- ### CDN 方式
25
-
21
+ **CDN:**
26
22
  ```html
27
- <!-- UMD 版本已内置 PeerJS,只需引入一个文件 -->
28
23
  <script src="https://unpkg.com/sx-peerjs-http-util/dist/index.umd.js"></script>
29
24
  ```
30
25
 
31
- ## 使用方式
32
-
33
- ### PeerJsWrapper 类
26
+ ## 快速开始
34
27
 
35
28
  ```typescript
36
29
  import { PeerJsWrapper } from 'sx-peerjs-http-util';
37
30
 
38
- // 创建实例(不指定 ID 则自动生成 UUID)
39
31
  const wrapper = new PeerJsWrapper();
40
-
41
- // 或指定 Peer ID
42
- // const wrapper = new PeerJsWrapper('my-custom-id');
43
-
44
- // 等待连接就绪
45
32
  await wrapper.whenReady();
46
33
 
47
- // 获取 Peer ID(同步方法)
48
- const peerId = wrapper.getPeerId();
49
- console.log('My Peer ID:', peerId);
50
- ```
51
-
52
- ### 发送请求 (send)
53
-
54
- ```typescript
55
- // 发送请求到对端设备
56
- const data = await wrapper.send('remote-peer-id', '/api/hello', { name: 'world' });
57
- console.log(data); // 直接输出响应数据(自动拆箱)
58
- ```
59
-
60
- ### 注册处理器 (registerHandler)
61
-
62
- ```typescript
63
- // 服务端注册处理器
34
+ // 注册处理器
64
35
  wrapper.registerHandler('/api/hello', (from, data) => {
65
- return { message: 'hello', received: data }; // 直接返回数据,自动装箱
36
+ return { message: 'hello', received: data };
66
37
  });
67
38
 
68
- // 注销处理器
69
- wrapper.unregisterHandler('/api/hello');
39
+ // 发送请求(自动路由)
40
+ const data = await wrapper.send('remote-peer-id', '/api/hello', { name: 'world' });
70
41
  ```
71
42
 
72
- ### 语音/视频通话
43
+ ## 语音/视频通话
73
44
 
74
45
  ```typescript
75
- // 发起语音通话
76
- const callSession = await wrapper.call('remote-peer-id', { video: false });
77
-
78
- // 发起视频通话
79
- // const callSession = await wrapper.call('remote-peer-id', { video: true });
46
+ // 发起通话
47
+ const call = await wrapper.call('remote-peer-id', { video: true });
80
48
 
81
49
  // 监听来电
82
- wrapper.onIncomingCall((event) => {
83
- console.log('来电:', event.from, event.hasVideo ? '视频' : '语音');
84
-
85
- // 接听
86
- const session = await event.answer();
87
-
88
- // 或拒绝
89
- // event.reject();
90
- });
91
-
92
- // 获取媒体流用于显示
93
- const remoteStream = callSession.getRemoteStream();
94
- const localStream = callSession.getLocalStream();
95
-
96
- // 控制通话
97
- callSession.toggleMute(); // 切换静音
98
- callSession.toggleVideo(); // 切换视频开关
99
- callSession.hangUp(); // 挂断
100
-
101
- // 监听通话状态
102
- callSession.onStateChange((state, reason) => {
103
- console.log('通话状态:', state); // 'connecting' | 'connected' | 'ended'
50
+ wrapper.onIncomingCall(async (event) => {
51
+ const session = await event.answer(); // 接听
52
+ // 或 event.reject(); // 拒绝
104
53
  });
105
54
  ```
106
55
 
107
- ### 销毁实例 (destroy)
108
-
109
- ```typescript
110
- wrapper.destroy();
111
- ```
112
-
113
- ## 完整示例
114
-
115
- ### NPM 方式 - 服务器端
116
-
117
- ```html
118
- <!DOCTYPE html>
119
- <html>
120
- <head>
121
- <script src="https://unpkg.com/peerjs@1.5.5/dist/peerjs.min.js"></script>
122
- </head>
123
- <body>
124
- <h1>Server</h1>
125
- <div id="peer-id"></div>
126
-
127
- <script type="module">
128
- import { PeerJsWrapper } from 'https://unpkg.com/sx-peerjs-http-util/dist/index.esm.js';
129
-
130
- const wrapper = new PeerJsWrapper();
131
-
132
- wrapper.registerHandler('/api/hello', (from, data) => {
133
- return { message: 'Hello from server', received: data };
134
- });
135
-
136
- wrapper.whenReady().then(() => {
137
- document.getElementById('peer-id').textContent = `Peer ID: ${wrapper.getPeerId()}`;
138
- });
139
- </script>
140
- </body>
141
- </html>
142
- ```
143
-
144
- ### CDN 方式 - 服务器端
145
-
146
- ```html
147
- <!DOCTYPE html>
148
- <html>
149
- <head>
150
- <!-- CDN 版本已内置 PeerJS -->
151
- <script src="https://unpkg.com/sx-peerjs-http-util/dist/index.umd.js"></script>
152
- </head>
153
- <body>
154
- <h1>Server</h1>
155
- <div id="peer-id"></div>
156
-
157
- <script>
158
- const wrapper = new PeerJsHttpUtil.PeerJsWrapper();
159
-
160
- wrapper.registerHandler('/api/hello', (from, data) => {
161
- return { message: 'Hello from server', received: data };
162
- });
163
-
164
- wrapper.whenReady().then(() => {
165
- document.getElementById('peer-id').textContent = `Peer ID: ${wrapper.getPeerId()}`;
166
- });
167
- </script>
168
- </body>
169
- </html>
170
- ```
171
-
172
- ### 客户端
173
-
174
- ```html
175
- <!DOCTYPE html>
176
- <html>
177
- <head>
178
- <script src="https://unpkg.com/sx-peerjs-http-util/dist/index.umd.js"></script>
179
- </head>
180
- <body>
181
- <h1>Client</h1>
182
- <button onclick="sendRequest()">Send Request</button>
183
-
184
- <script>
185
- const wrapper = new PeerJsHttpUtil.PeerJsWrapper();
186
-
187
- async function sendRequest() {
188
- try {
189
- const data = await wrapper.send('server-peer-id', '/api/hello', { test: 'data' });
190
- console.log('Response:', data);
191
- } catch (err) {
192
- console.error('Error:', err.message);
193
- }
194
- }
195
- </script>
196
- </body>
197
- </html>
198
- ```
199
-
200
- ## API 参考
201
-
202
- ### `new PeerJsWrapper(peerId?: string, isDebug?: boolean, server?: ServerConfig)`
203
-
204
- 创建 PeerJsWrapper 实例。
205
-
206
- - `peerId` (可选): 指定 Peer ID,不提供则自动生成 UUID
207
- - `isDebug` (可选): 是否开启调试模式,开启后会打印事件日志,格式为 `{对象} {事件名} {事件变量}`
208
- - `server` (可选): 自定义信令服务器配置,不提供则使用 PeerJS 公共服务器
209
- - `host`: 服务器地址
210
- - `port`: 端口号
211
- - `path`: 路径(如 `/peerjs`)
212
- - `secure`: 是否使用 HTTPS/WSS
213
-
214
- ### `getPeerId(): string`
215
-
216
- 获取当前 Peer ID(同步方法,立即返回)。
217
-
218
- ### `whenReady(): Promise<void>`
219
-
220
- 等待 Peer 连接到信令服务器。
221
-
222
- ### `send(peerId: string, path: string, data?: unknown): Promise<unknown>`
223
-
224
- 发送请求到指定 Peer。
225
-
226
- - `peerId`: 对端设备 ID
227
- - `path`: 请求路径
228
- - `data`: 请求数据 (可选)
229
- - 返回: 响应数据(自动拆箱,只返回 data 部分)
230
-
231
- ### `registerHandler(path: string, handler: SimpleHandler): void`
232
-
233
- 注册路径处理器。
234
-
235
- - `path`: 请求路径
236
- - `handler`: 处理器函数,签名 `(from: string, data?: unknown) => Promise<unknown> | unknown`
237
-
238
- ### `unregisterHandler(path: string): void`
239
-
240
- 注销路径处理器。
241
-
242
- ### `call(peerId: string, options?: CallOptions): Promise<CallSession>`
243
-
244
- 发起语音/视频通话。
245
-
246
- - `peerId`: 对端设备 ID
247
- - `options`: 通话选项
248
- - `video`: 是否启用视频(默认 false)
249
- - `metadata`: 自定义元数据
250
- - 返回: `CallSession` 通话会话对象
251
-
252
- ### `onIncomingCall(listener: IncomingCallListener): void`
253
-
254
- 注册来电监听器。
255
-
256
- - `listener`: 监听器函数,接收 `IncomingCallEvent` 对象
257
-
258
- ### `offIncomingCall(listener: IncomingCallListener): void`
259
-
260
- 移除来电监听器。
261
-
262
- ### `getActiveCall(): CallSession | null`
263
-
264
- 获取当前活跃的通话会话。
265
-
266
- ### `destroy(): void`
267
-
268
- 关闭所有连接并销毁实例(会自动挂断活跃通话)。
269
-
270
- ## CallSession 接口
271
-
272
- 通话会话对象,用于控制通话。
273
-
274
- | 属性/方法 | 说明 |
275
- |-----------|------|
276
- | `peerId` | 对端的 Peer ID |
277
- | `hasVideo` | 是否包含视频 |
278
- | `isConnected` | 是否已连接 |
279
- | `getLocalStream()` | 获取本地媒体流 |
280
- | `getRemoteStream()` | 获取远程媒体流 |
281
- | `toggleMute()` | 切换静音状态,返回新的静音状态 |
282
- | `toggleVideo()` | 切换视频开关,返回新的视频状态 |
283
- | `hangUp()` | 挂断通话 |
284
- | `onStateChange(listener)` | 注册状态变化监听器 |
285
- | `offStateChange(listener)` | 移除状态变化监听器 |
286
-
287
- ## IncomingCallEvent 接口
288
-
289
- 来电事件对象。
290
-
291
- | 属性/方法 | 说明 |
292
- |-----------|------|
293
- | `from` | 呼叫者的 Peer ID |
294
- | `hasVideo` | 是否包含视频 |
295
- | `metadata` | 呼叫者传递的元数据 |
296
- | `answer()` | 接听来电,返回 `Promise<CallSession>` |
297
- | `reject()` | 拒绝来电 |
298
-
299
- ## E2E 测试
300
-
301
- ```bash
302
- npm run test:e2e
303
- ```
304
-
305
- ## 注意事项
56
+ ## API 文档
306
57
 
307
- - 每次请求都会创建新的 Peer 连接,请求完成后会自动清理
308
- - 请求超时时间为 30 秒
309
- - 此库仅用于浏览器环境
310
- - 需要使用 PeerJS 信令服务器(默认使用公共服务器)
311
- - CDN 版本 (UMD) 已内置 PeerJS,无需额外引入
312
- - NPM 版本需要单独安装 peerjs 依赖
313
- - **自动断线重连**:网络断开时会自动尝试重连(每秒重试一次)
314
- - **语音/视频通话**:同一时间只能有一个活跃通话,通话超时 30 秒无应答自动挂断
58
+ 完整 API 文档见 [docs/api.md](docs/api.md)
315
59
 
316
- ## 发布
60
+ ## 注意
317
61
 
318
- - NPM: https://www.npmjs.com/package/sx-peerjs-http-util
319
- - CDN: https://unpkg.com/sx-peerjs-http-util/dist/index.umd.js
62
+ - 仅限浏览器环境
63
+ - 请求超时 30 秒
64
+ - 每次请求创建新连接
@@ -0,0 +1,99 @@
1
+ /**
2
+ * CallSessionImpl - 通话会话的内部实现
3
+ *
4
+ * 负责管理单个语音/视频通话的完整生命周期:
5
+ * - 音视频流管理
6
+ * - 静音/视频开关状态
7
+ * - 通话状态变化通知
8
+ *
9
+ * @example
10
+ * const session = new CallSessionImpl(peerId, mediaConnection, hasVideo, debugLog, onCleanup);
11
+ * session.toggleMute(); // 切换静音
12
+ * session.toggleVideo(); // 切换视频
13
+ * session.hangUp(); // 挂断通话
14
+ */
15
+ import type { MediaConnection } from 'peerjs';
16
+ import type { CallSession, CallState, CallStateListener } from './types';
17
+ /**
18
+ * 通话会话实现类
19
+ * 实现 CallSession 接口,提供通话控制功能
20
+ */
21
+ export declare class CallSessionImpl implements CallSession {
22
+ /** 对端的 Peer ID */
23
+ readonly peerId: string;
24
+ /** 是否包含视频 */
25
+ readonly hasVideo: boolean;
26
+ /** PeerJS MediaConnection 实例 */
27
+ private mediaConnection;
28
+ /** 本地媒体流(麦克风/摄像头) */
29
+ private localStream;
30
+ /** 远程媒体流(对方的音频/视频) */
31
+ private remoteStream;
32
+ /** 通话状态监听器集合 */
33
+ private stateListeners;
34
+ /** 调试日志函数 */
35
+ private debugLogFn;
36
+ /** 清理回调(通话结束时调用) */
37
+ private onCleanup;
38
+ /** 当前通话状态 */
39
+ private _state;
40
+ /** 是否已静音 */
41
+ private isMuted;
42
+ /** 视频是否开启 */
43
+ private isVideoEnabled;
44
+ /**
45
+ * 创建通话会话实例
46
+ * @param peerId 对端 Peer ID
47
+ * @param mediaConnection PeerJS MediaConnection 实例
48
+ * @param hasVideo 是否包含视频
49
+ * @param debugLog 调试日志函数
50
+ * @param onCleanup 通话结束时的清理回调
51
+ */
52
+ constructor(peerId: string, mediaConnection: MediaConnection, hasVideo: boolean, debugLog: (obj: string, event: string, data?: unknown) => void, onCleanup: (session: CallSessionImpl) => void);
53
+ /** 是否已连接 */
54
+ get isConnected(): boolean;
55
+ /** 当前通话状态 */
56
+ get state(): CallState;
57
+ /**
58
+ * 设置通话状态
59
+ * @param state 新的通话状态
60
+ * @param reason 状态变化原因(可选)
61
+ */
62
+ setState(state: CallState, reason?: string): void;
63
+ /** 设置本地媒体流 */
64
+ setLocalStream(stream: MediaStream): void;
65
+ /** 设置远程媒体流 */
66
+ setRemoteStream(stream: MediaStream): void;
67
+ /** 获取本地媒体流 */
68
+ getLocalStream(): MediaStream | null;
69
+ /** 获取远程媒体流 */
70
+ getRemoteStream(): MediaStream | null;
71
+ /**
72
+ * 切换静音状态
73
+ * @returns 切换后的静音状态(true = 已静音)
74
+ */
75
+ toggleMute(): boolean;
76
+ /**
77
+ * 切换视频开关(仅视频通话有效)
78
+ * @returns 切换后的视频状态(true = 视频开启)
79
+ */
80
+ toggleVideo(): boolean;
81
+ /** 挂断通话 */
82
+ hangUp(): void;
83
+ /**
84
+ * 关闭通话会话
85
+ * 停止本地流,清理资源
86
+ */
87
+ close(): void;
88
+ /** 注册通话状态变化监听器 */
89
+ onStateChange(listener: CallStateListener): void;
90
+ /** 移除通话状态变化监听器 */
91
+ offStateChange(listener: CallStateListener): void;
92
+ /**
93
+ * 通知状态变化
94
+ * @param state 新状态
95
+ * @param reason 变化原因(可选)
96
+ */
97
+ private notifyStateChange;
98
+ }
99
+ //# sourceMappingURL=CallSession.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CallSession.d.ts","sourceRoot":"","sources":["../src/CallSession.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEzE;;;GAGG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,kBAAkB;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,aAAa;IACb,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B,gCAAgC;IAChC,OAAO,CAAC,eAAe,CAAkB;IACzC,qBAAqB;IACrB,OAAO,CAAC,WAAW,CAA4B;IAC/C,sBAAsB;IACtB,OAAO,CAAC,YAAY,CAA4B;IAChD,gBAAgB;IAChB,OAAO,CAAC,cAAc,CAAgC;IACtD,aAAa;IACb,OAAO,CAAC,UAAU,CAAuD;IACzE,oBAAoB;IACpB,OAAO,CAAC,SAAS,CAAqC;IAEtD,aAAa;IACb,OAAO,CAAC,MAAM,CAA2B;IACzC,YAAY;IACZ,OAAO,CAAC,OAAO,CAAS;IACxB,aAAa;IACb,OAAO,CAAC,cAAc,CAAQ;IAE9B;;;;;;;OAOG;gBAED,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,eAAe,EAChC,QAAQ,EAAE,OAAO,EACjB,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,EAC9D,SAAS,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI;IAS/C,YAAY;IACZ,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,aAAa;IACb,IAAI,KAAK,IAAI,SAAS,CAErB;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAKjD,cAAc;IACd,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAIzC,cAAc;IACd,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAI1C,cAAc;IACd,cAAc,IAAI,WAAW,GAAG,IAAI;IAIpC,cAAc;IACd,eAAe,IAAI,WAAW,GAAG,IAAI;IAIrC;;;OAGG;IACH,UAAU,IAAI,OAAO;IAYrB;;;OAGG;IACH,WAAW,IAAI,OAAO;IAYtB,WAAW;IACX,MAAM,IAAI,IAAI;IAKd;;;OAGG;IACH,KAAK,IAAI,IAAI;IASb,kBAAkB;IAClB,aAAa,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAIhD,kBAAkB;IAClB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAIjD;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAe1B"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * MessageHandler - 消息处理模块
3
+ *
4
+ * 负责处理接收到的各类消息:
5
+ * - 直连请求(request)
6
+ * - 中继请求(relay-request)
7
+ * - 路由更新(route-update)
8
+ *
9
+ * 中继请求处理流程:
10
+ * 1. 收到 relay-request 消息
11
+ * 2. 如果是目标节点,处理请求并返回响应
12
+ * 3. 如果不是目标节点,根据 forwardPath 转发到下一个节点
13
+ * 4. 如果 forwardPath 为空,尝试直连到目标节点
14
+ *
15
+ * @example
16
+ * const handler = new MessageHandler(callbacks);
17
+ * const response = await handler.handleRequest(from, request, relayMessage);
18
+ */
19
+ import type { Peer } from 'peerjs';
20
+ import type { Request, Response, SimpleHandler, RelayMessage } from './types';
21
+ /**
22
+ * 消息处理器回调接口
23
+ */
24
+ export interface MessageHandlerCallbacks {
25
+ /** 获取本地 Peer ID */
26
+ getMyPeerId(): string;
27
+ /** 获取 PeerJS 实例 */
28
+ getPeerInstance(): Peer | null;
29
+ /** 等待连接就绪 */
30
+ waitForReady(): Promise<void>;
31
+ /** 获取处理器映射表 */
32
+ getSimpleHandlers(): Map<string, SimpleHandler>;
33
+ /** 调试日志函数 */
34
+ debugLog: (obj: string, event: string, data?: unknown) => void;
35
+ /** 路由更新回调(可选) */
36
+ onRouteUpdate?: (fromPeerId: string, message: RelayMessage) => void;
37
+ }
38
+ /**
39
+ * 消息处理器类
40
+ * 负责解析和处理接收到的各类消息
41
+ */
42
+ export declare class MessageHandler {
43
+ /** 回调函数集合 */
44
+ private callbacks;
45
+ /**
46
+ * 创建消息处理器
47
+ * @param callbacks 回调函数集合
48
+ */
49
+ constructor(callbacks: MessageHandlerCallbacks);
50
+ /**
51
+ * 处理收到的请求
52
+ * 根据是否有中继消息上下文判断是直连请求还是中继请求
53
+ * @param from 发送者 Peer ID
54
+ * @param request 请求数据
55
+ * @param relayMessage 中继消息上下文(可选,有则为中继请求)
56
+ * @returns 响应数据
57
+ */
58
+ handleRequest(from: string, request: Request, relayMessage?: RelayMessage): Promise<Response>;
59
+ /**
60
+ * 处理直连请求
61
+ * @param from 发送者 Peer ID
62
+ * @param request 请求数据
63
+ * @returns 响应数据
64
+ */
65
+ private handleDirectRequest;
66
+ /**
67
+ * 处理中继请求
68
+ * @param from 发送者 Peer ID
69
+ * @param request 请求数据
70
+ * @param relayMessage 中继消息上下文
71
+ * @returns 响应数据
72
+ */
73
+ private handleRelayRequest;
74
+ /**
75
+ * 调用注册的处理器
76
+ * @param path 请求路径
77
+ * @param from 发送者 Peer ID
78
+ * @param data 请求数据
79
+ * @returns 处理器返回的数据,或 404 错误
80
+ */
81
+ processHandler(path: string, from: string, data?: unknown): Promise<unknown>;
82
+ /**
83
+ * 判断结果是否为错误响应
84
+ */
85
+ private isErrorResponse;
86
+ /**
87
+ * 创建连接并发送中继消息的通用方法
88
+ * @param targetId 目标节点 ID
89
+ * @param message 要发送的消息
90
+ * @param extractResponse 从响应消息中提取数据的函数
91
+ * @returns Promise<Response>
92
+ */
93
+ private createConnectionAndSend;
94
+ /**
95
+ * 转发中继请求到下一个节点
96
+ * @param nextHop 下一跳节点 ID
97
+ * @param message 要转发的消息
98
+ * @returns 响应数据
99
+ */
100
+ private forwardRelay;
101
+ /**
102
+ * 转发到最终目标节点(当没有更多中继节点时使用)
103
+ * @param targetId 目标节点 ID
104
+ * @param request 请求数据
105
+ * @param originalMessage 原始中继消息
106
+ * @returns 响应数据
107
+ */
108
+ private forwardToTarget;
109
+ }
110
+ //# sourceMappingURL=MessageHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../src/MessageHandler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG9E;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,mBAAmB;IACnB,WAAW,IAAI,MAAM,CAAC;IACtB,mBAAmB;IACnB,eAAe,IAAI,IAAI,GAAG,IAAI,CAAC;IAC/B,aAAa;IACb,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,eAAe;IACf,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAChD,aAAa;IACb,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/D,iBAAiB;IACjB,aAAa,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;CACrE;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,aAAa;IACb,OAAO,CAAC,SAAS,CAA0B;IAE3C;;;OAGG;gBACS,SAAS,EAAE,uBAAuB;IAI9C;;;;;;;OAOG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC;IAOnG;;;;;OAKG;YACW,mBAAmB;IAQjC;;;;;;OAMG;YACW,kBAAkB;IAuDhC;;;;;;OAMG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAUlF;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAsD/B;;;;;OAKG;YACW,YAAY;IAa1B;;;;;;OAMG;YACW,eAAe;CA2B9B"}