egos-transfer 0.2.7 → 0.2.8
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/dist/connection-manager.js +12 -8
- package/dist/peer-transfer.d.ts +1 -0
- package/dist/peer-transfer.js +30 -11
- package/package.json +1 -1
- package/src/connection-manager.ts +8 -5
- package/src/peer-transfer.ts +29 -12
|
@@ -81,25 +81,26 @@ class ConnectionManager {
|
|
|
81
81
|
return conn;
|
|
82
82
|
}
|
|
83
83
|
remove(peerId, connectionId) {
|
|
84
|
-
var _a, _b;
|
|
84
|
+
var _a, _b, _c, _d, _e;
|
|
85
85
|
const conn = this.pool.get(peerId);
|
|
86
86
|
if (conn) {
|
|
87
87
|
if (connectionId && conn.connectionId !== connectionId)
|
|
88
88
|
return;
|
|
89
89
|
this.pool.delete(peerId);
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
// 先 close 触发 close 事件(handleConnClosed 会结算 in-flight 请求),
|
|
91
|
+
// 再清理监听器与 PeerJS 内部引用,避免僵尸连接堆积导致无法建立新连接
|
|
92
|
+
conn.close();
|
|
93
|
+
(_b = (_a = conn).__cm_stateChangeCleanup) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
94
|
+
conn.removeAllListeners();
|
|
95
|
+
(_c = this.deps.getPeer()) === null || _c === void 0 ? void 0 : _c._removeConnection(conn);
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
97
98
|
// 清理 Peer 内部残留的 connection 引用
|
|
98
|
-
const connections = ((
|
|
99
|
+
const connections = ((_d = this.deps.getPeer()) === null || _d === void 0 ? void 0 : _d.connections) || {};
|
|
99
100
|
for (const c of connections[peerId] || []) {
|
|
100
101
|
c.removeAllListeners();
|
|
101
102
|
c.close();
|
|
102
|
-
(
|
|
103
|
+
(_e = this.deps.getPeer()) === null || _e === void 0 ? void 0 : _e._removeConnection(c);
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
}
|
|
@@ -111,7 +112,10 @@ class ConnectionManager {
|
|
|
111
112
|
return ['connected', 'completed'].includes(conn.peerConnection.connectionState);
|
|
112
113
|
}
|
|
113
114
|
handleConnClosed(conn) {
|
|
115
|
+
var _a;
|
|
114
116
|
this.pool.delete(conn.peer);
|
|
117
|
+
// 同步移除 PeerJS 内部引用,避免僵尸连接堆积
|
|
118
|
+
(_a = this.deps.getPeer()) === null || _a === void 0 ? void 0 : _a._removeConnection(conn);
|
|
115
119
|
this.deps.onConnClosed(conn);
|
|
116
120
|
}
|
|
117
121
|
// ── Health check ─────────────────────────────────────────────────
|
package/dist/peer-transfer.d.ts
CHANGED
package/dist/peer-transfer.js
CHANGED
|
@@ -55,10 +55,9 @@ class PeerTransfer {
|
|
|
55
55
|
// ── Peer lifecycle ──────────────────────────────────────────────
|
|
56
56
|
createPeer(force) {
|
|
57
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
var _a
|
|
59
|
-
console.info('createPeer##', (_a = this.peer) === null || _a === void 0 ? void 0 : _a.open, force);
|
|
58
|
+
var _a;
|
|
60
59
|
this._exited = false;
|
|
61
|
-
if (((
|
|
60
|
+
if (((_a = this.peer) === null || _a === void 0 ? void 0 : _a.open) && !force) {
|
|
62
61
|
return this.peer;
|
|
63
62
|
}
|
|
64
63
|
this.destroyPeer();
|
|
@@ -68,7 +67,13 @@ class PeerTransfer {
|
|
|
68
67
|
yield this.waitForOpen(peer);
|
|
69
68
|
this.destroyed = false;
|
|
70
69
|
peer.on('close', () => {
|
|
71
|
-
|
|
70
|
+
// 仅当 Peer 非主动销毁(stop/clearInstance/重建)时才重连
|
|
71
|
+
setTimeout(() => {
|
|
72
|
+
if (this.destroyed || this._exited) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
this.reconnect();
|
|
76
|
+
}, exports.PEER_CLOSE_RECONNECT_TIMEOUT);
|
|
72
77
|
});
|
|
73
78
|
peer.on('error', (err) => {
|
|
74
79
|
// 覆盖所有与 signaling server 断连相关的错误类型
|
|
@@ -88,6 +93,10 @@ class PeerTransfer {
|
|
|
88
93
|
socket === null || socket === void 0 ? void 0 : socket.on('message', (message) => {
|
|
89
94
|
this.handleSocketMessage(message);
|
|
90
95
|
});
|
|
96
|
+
// signaling socket 断开时主动重连(兜底:部分场景不触发 peer error)
|
|
97
|
+
socket === null || socket === void 0 ? void 0 : socket.on('disconnected', () => {
|
|
98
|
+
this.reconnect();
|
|
99
|
+
});
|
|
91
100
|
// 启动连接健康检查
|
|
92
101
|
this.connectionManager.startHealthCheck();
|
|
93
102
|
// 启动空闲重连定时器
|
|
@@ -144,6 +153,9 @@ class PeerTransfer {
|
|
|
144
153
|
case 'HEARTBEAT':
|
|
145
154
|
this.resetHeartbeatTimer();
|
|
146
155
|
break;
|
|
156
|
+
case 'RELOAD':
|
|
157
|
+
this.reconnect(true);
|
|
158
|
+
break;
|
|
147
159
|
case 'ERROR':
|
|
148
160
|
if (((_a = message.payload) === null || _a === void 0 ? void 0 : _a.msg) === constant_1.CONNECTION_PEER_CONFLICT) {
|
|
149
161
|
this.getStore().dispatch({
|
|
@@ -152,6 +164,9 @@ class PeerTransfer {
|
|
|
152
164
|
});
|
|
153
165
|
}
|
|
154
166
|
break;
|
|
167
|
+
default:
|
|
168
|
+
console.log('unknown socket message type', message);
|
|
169
|
+
break;
|
|
155
170
|
}
|
|
156
171
|
}
|
|
157
172
|
// ── Connection management ───────────────────────────────────────
|
|
@@ -257,13 +272,6 @@ class PeerTransfer {
|
|
|
257
272
|
onConnClosed(conn) {
|
|
258
273
|
const reqIds = this.connRequests.get(conn.connectionId);
|
|
259
274
|
if (reqIds) {
|
|
260
|
-
// for (const reqId of reqIds) {
|
|
261
|
-
// const cb = this.requests.get(reqId);
|
|
262
|
-
// if (cb) {
|
|
263
|
-
// cb({ error: { message: 'connection closed', code: 'CONN_CLOSED' } } as any);
|
|
264
|
-
// this.requests.delete(reqId);
|
|
265
|
-
// }
|
|
266
|
-
// }
|
|
267
275
|
this.connRequests.delete(conn.connectionId);
|
|
268
276
|
}
|
|
269
277
|
}
|
|
@@ -561,5 +569,16 @@ class PeerTransfer {
|
|
|
561
569
|
(_b = this.peer) === null || _b === void 0 ? void 0 : _b.removeAllListeners();
|
|
562
570
|
this.peer = undefined;
|
|
563
571
|
}
|
|
572
|
+
askReload(peerId) {
|
|
573
|
+
var _a;
|
|
574
|
+
(_a = this.peer) === null || _a === void 0 ? void 0 : _a.socket.send({
|
|
575
|
+
type: 'RELOAD',
|
|
576
|
+
payload: {
|
|
577
|
+
type: 'RELOAD',
|
|
578
|
+
src: this.peerId,
|
|
579
|
+
dst: peerId,
|
|
580
|
+
},
|
|
581
|
+
});
|
|
582
|
+
}
|
|
564
583
|
}
|
|
565
584
|
exports.PeerTransfer = PeerTransfer;
|
package/package.json
CHANGED
|
@@ -103,11 +103,12 @@ export class ConnectionManager {
|
|
|
103
103
|
if (conn) {
|
|
104
104
|
if (connectionId && conn.connectionId !== connectionId) return;
|
|
105
105
|
this.pool.delete(peerId);
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
// 先 close 触发 close 事件(handleConnClosed 会结算 in-flight 请求),
|
|
107
|
+
// 再清理监听器与 PeerJS 内部引用,避免僵尸连接堆积导致无法建立新连接
|
|
108
|
+
conn.close();
|
|
109
|
+
(conn as any).__cm_stateChangeCleanup?.();
|
|
110
|
+
conn.removeAllListeners();
|
|
111
|
+
this.deps.getPeer()?._removeConnection(conn);
|
|
111
112
|
} else {
|
|
112
113
|
// 清理 Peer 内部残留的 connection 引用
|
|
113
114
|
const connections = this.deps.getPeer()?.connections || {};
|
|
@@ -127,6 +128,8 @@ export class ConnectionManager {
|
|
|
127
128
|
|
|
128
129
|
private handleConnClosed(conn: DataConnection): void {
|
|
129
130
|
this.pool.delete(conn.peer);
|
|
131
|
+
// 同步移除 PeerJS 内部引用,避免僵尸连接堆积
|
|
132
|
+
this.deps.getPeer()?._removeConnection(conn);
|
|
130
133
|
this.deps.onConnClosed(conn);
|
|
131
134
|
}
|
|
132
135
|
|
package/src/peer-transfer.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
PING_TIMEOUT,
|
|
8
8
|
UNAUTHORIZED,
|
|
9
9
|
} from './constant';
|
|
10
|
-
import { DataConnection, Peer, PeerOptions } from 'peerjs';
|
|
10
|
+
import { DataConnection, Peer, PeerOptions, ServerMessageType } from 'peerjs';
|
|
11
11
|
import {
|
|
12
12
|
IDeviceStatus,
|
|
13
13
|
IMessage,
|
|
@@ -89,11 +89,11 @@ export abstract class PeerTransfer {
|
|
|
89
89
|
// ── Peer lifecycle ──────────────────────────────────────────────
|
|
90
90
|
|
|
91
91
|
async createPeer(force?: boolean): Promise<Peer> {
|
|
92
|
-
console.info('createPeer##', this.peer?.open, force);
|
|
93
92
|
this._exited = false;
|
|
94
93
|
if (this.peer?.open && !force) {
|
|
95
94
|
return this.peer;
|
|
96
95
|
}
|
|
96
|
+
console.info('create peer', Date.now());
|
|
97
97
|
this.destroyPeer();
|
|
98
98
|
await this.reloadConfig();
|
|
99
99
|
|
|
@@ -103,7 +103,13 @@ export abstract class PeerTransfer {
|
|
|
103
103
|
await this.waitForOpen(peer);
|
|
104
104
|
this.destroyed = false;
|
|
105
105
|
peer.on('close', () => {
|
|
106
|
-
|
|
106
|
+
// 仅当 Peer 非主动销毁(stop/clearInstance/重建)时才重连
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
if (this.destroyed || this._exited) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
this.reconnect();
|
|
112
|
+
}, PEER_CLOSE_RECONNECT_TIMEOUT);
|
|
107
113
|
});
|
|
108
114
|
|
|
109
115
|
peer.on('error', (err) => {
|
|
@@ -128,6 +134,10 @@ export abstract class PeerTransfer {
|
|
|
128
134
|
socket?.on('message', (message: IMessage) => {
|
|
129
135
|
this.handleSocketMessage(message);
|
|
130
136
|
});
|
|
137
|
+
// signaling socket 断开时主动重连(兜底:部分场景不触发 peer error)
|
|
138
|
+
socket?.on('disconnected', () => {
|
|
139
|
+
this.reconnect();
|
|
140
|
+
});
|
|
131
141
|
|
|
132
142
|
// 启动连接健康检查
|
|
133
143
|
this.connectionManager.startHealthCheck();
|
|
@@ -190,6 +200,9 @@ export abstract class PeerTransfer {
|
|
|
190
200
|
case 'HEARTBEAT':
|
|
191
201
|
this.resetHeartbeatTimer();
|
|
192
202
|
break;
|
|
203
|
+
case 'RELOAD':
|
|
204
|
+
this.reconnect(true);
|
|
205
|
+
break;
|
|
193
206
|
case 'ERROR':
|
|
194
207
|
if (message.payload?.msg === CONNECTION_PEER_CONFLICT) {
|
|
195
208
|
this.getStore().dispatch({
|
|
@@ -198,6 +211,8 @@ export abstract class PeerTransfer {
|
|
|
198
211
|
});
|
|
199
212
|
}
|
|
200
213
|
break;
|
|
214
|
+
default:
|
|
215
|
+
break;
|
|
201
216
|
}
|
|
202
217
|
}
|
|
203
218
|
|
|
@@ -309,13 +324,6 @@ export abstract class PeerTransfer {
|
|
|
309
324
|
private onConnClosed(conn: DataConnection) {
|
|
310
325
|
const reqIds = this.connRequests.get(conn.connectionId);
|
|
311
326
|
if (reqIds) {
|
|
312
|
-
// for (const reqId of reqIds) {
|
|
313
|
-
// const cb = this.requests.get(reqId);
|
|
314
|
-
// if (cb) {
|
|
315
|
-
// cb({ error: { message: 'connection closed', code: 'CONN_CLOSED' } } as any);
|
|
316
|
-
// this.requests.delete(reqId);
|
|
317
|
-
// }
|
|
318
|
-
// }
|
|
319
327
|
this.connRequests.delete(conn.connectionId);
|
|
320
328
|
}
|
|
321
329
|
}
|
|
@@ -351,7 +359,6 @@ export abstract class PeerTransfer {
|
|
|
351
359
|
if (this.destroyed) {
|
|
352
360
|
return { ...payload, body: {}, error: { message: 'destroyed', code: 'CONN_CLOSED' } } as any;
|
|
353
361
|
}
|
|
354
|
-
|
|
355
362
|
const conn = await this.connectToPeer(peerId);
|
|
356
363
|
if (!this.isValidConnection(conn)) {
|
|
357
364
|
return {
|
|
@@ -554,6 +561,7 @@ export abstract class PeerTransfer {
|
|
|
554
561
|
// ── Router integration ──────────────────────────────────────────
|
|
555
562
|
|
|
556
563
|
async onRequest(conn: DataConnection, message: PeerMessage) {
|
|
564
|
+
console.info('onRequest===>', message.route);
|
|
557
565
|
this.resetIdleTimer();
|
|
558
566
|
try {
|
|
559
567
|
await this.router.run(conn, message);
|
|
@@ -563,6 +571,7 @@ export abstract class PeerTransfer {
|
|
|
563
571
|
}
|
|
564
572
|
|
|
565
573
|
async onResponse(_conn: DataConnection, message: PeerMessage) {
|
|
574
|
+
console.info('onResponse<====', message.route);
|
|
566
575
|
this.resetIdleTimer();
|
|
567
576
|
// 优先检查 health check ping 回调
|
|
568
577
|
const cb = this.requests.get(message.requestId);
|
|
@@ -618,7 +627,7 @@ export abstract class PeerTransfer {
|
|
|
618
627
|
}
|
|
619
628
|
this.heartbeatTimer = setTimeout(() => {
|
|
620
629
|
if (!this.destroyed) {
|
|
621
|
-
this.reconnect(
|
|
630
|
+
this.reconnect();
|
|
622
631
|
}
|
|
623
632
|
}, HEARTBEAT_TIMEOUT);
|
|
624
633
|
}
|
|
@@ -668,4 +677,12 @@ export abstract class PeerTransfer {
|
|
|
668
677
|
this.peer?.removeAllListeners();
|
|
669
678
|
this.peer = undefined;
|
|
670
679
|
}
|
|
680
|
+
|
|
681
|
+
askReload(peerId: string) {
|
|
682
|
+
this.peer?.socket.send({
|
|
683
|
+
type: 'RELOAD',
|
|
684
|
+
payload: {},
|
|
685
|
+
dst: peerId,
|
|
686
|
+
});
|
|
687
|
+
}
|
|
671
688
|
}
|