@marianmeres/webrtc 1.1.0 → 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/API.md +10 -2
- package/README.md +34 -0
- package/dist/types.d.ts +2 -0
- package/dist/webrtc-manager.js +25 -2
- package/package.json +1 -1
package/API.md
CHANGED
|
@@ -759,6 +759,9 @@ interface WebRtcManagerConfig {
|
|
|
759
759
|
/** Initial reconnection delay in ms (doubles each attempt). Default: 1000 */
|
|
760
760
|
reconnectDelay?: number;
|
|
761
761
|
|
|
762
|
+
/** Timeout in ms for full reconnection to reach connected state. Default: 30000 */
|
|
763
|
+
fullReconnectTimeout?: number;
|
|
764
|
+
|
|
762
765
|
/** Callback to control whether reconnection should proceed */
|
|
763
766
|
shouldReconnect?: (context: {
|
|
764
767
|
attempt: number;
|
|
@@ -942,19 +945,24 @@ When `autoReconnect: true`:
|
|
|
942
945
|
2. **Attempts 3+:** Full reconnection (new peer connection)
|
|
943
946
|
3. **Backoff:** `reconnectDelay * 2^(attempt-1)` milliseconds
|
|
944
947
|
|
|
945
|
-
|
|
948
|
+
#### Full Reconnection and Signaling
|
|
949
|
+
|
|
950
|
+
**Important:** For "full" strategy reconnections, the manager creates a new peer connection but **cannot automatically complete the signaling handshake**. You must listen for the `reconnecting` event and re-perform signaling when `strategy === 'full'`:
|
|
946
951
|
|
|
947
952
|
```typescript
|
|
948
|
-
manager.on('reconnecting', ({ attempt, strategy }) => {
|
|
953
|
+
manager.on('reconnecting', async ({ attempt, strategy }) => {
|
|
949
954
|
if (strategy === 'full') {
|
|
950
955
|
// Re-do offer/answer exchange
|
|
951
956
|
const offer = await manager.createOffer();
|
|
952
957
|
await manager.setLocalDescription(offer);
|
|
953
958
|
sendToRemote(offer);
|
|
954
959
|
}
|
|
960
|
+
// For 'ice-restart', the manager handles it automatically
|
|
955
961
|
});
|
|
956
962
|
```
|
|
957
963
|
|
|
964
|
+
If the connection doesn't reach `CONNECTED` state within `fullReconnectTimeout` (default: 30 seconds), it's treated as a failed attempt and the next reconnection attempt begins. When all attempts are exhausted, `EVENT_RECONNECT_FAILED` is emitted.
|
|
965
|
+
|
|
958
966
|
### Conditional Reconnection
|
|
959
967
|
|
|
960
968
|
Use the `shouldReconnect` callback to suppress reconnection when the peer disconnected intentionally:
|
package/README.md
CHANGED
|
@@ -51,6 +51,7 @@ const manager = new WebRtcManager(factory, config);
|
|
|
51
51
|
- `autoReconnect`: Enable automatic reconnection (default: false)
|
|
52
52
|
- `maxReconnectAttempts`: Max reconnection attempts (default: 5)
|
|
53
53
|
- `reconnectDelay`: Initial reconnection delay in ms (default: 1000)
|
|
54
|
+
- `fullReconnectTimeout`: Timeout in ms for full reconnection to succeed (default: 30000)
|
|
54
55
|
- `shouldReconnect`: Callback to control whether reconnection should proceed (see below)
|
|
55
56
|
- `debug`: Enable debug logging (default: false)
|
|
56
57
|
- `logger`: Custom logger instance implementing `Logger` interface (default: console)
|
|
@@ -161,6 +162,39 @@ The callback receives:
|
|
|
161
162
|
- `maxAttempts`: Configured maximum attempts
|
|
162
163
|
- `strategy`: `"ice-restart"` (attempts 1-2) or `"full"` (attempts 3+)
|
|
163
164
|
|
|
165
|
+
### Reconnection Strategies
|
|
166
|
+
|
|
167
|
+
The manager uses two reconnection strategies with exponential backoff:
|
|
168
|
+
|
|
169
|
+
1. **ICE Restart** (attempts 1-2): Lightweight reconnection that keeps the existing peer connection and restarts ICE negotiation. Works when the network path changed but the remote peer is still available.
|
|
170
|
+
|
|
171
|
+
2. **Full Reconnection** (attempts 3+): Creates a completely new peer connection. This is necessary when ICE restart fails, but **requires consumer action** to complete the signaling handshake.
|
|
172
|
+
|
|
173
|
+
#### Handling Full Reconnection
|
|
174
|
+
|
|
175
|
+
When a full reconnection is triggered, the manager will:
|
|
176
|
+
1. Clean up the old peer connection
|
|
177
|
+
2. Create a new peer connection
|
|
178
|
+
3. Emit `EVENT_RECONNECTING` with `strategy: 'full'`
|
|
179
|
+
|
|
180
|
+
**Important:** The manager cannot automatically complete the signaling handshake for full reconnections. You must listen for the `reconnecting` event and re-establish signaling when the strategy is `'full'`:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
manager.on(WebRtcManager.EVENT_RECONNECTING, async ({ attempt, strategy }) => {
|
|
184
|
+
console.log(`Reconnecting (attempt ${attempt}, strategy: ${strategy})`);
|
|
185
|
+
|
|
186
|
+
if (strategy === 'full') {
|
|
187
|
+
// Re-do the signaling handshake
|
|
188
|
+
const offer = await manager.createOffer();
|
|
189
|
+
await manager.setLocalDescription(offer);
|
|
190
|
+
signalingChannel.send({ type: 'offer', offer });
|
|
191
|
+
}
|
|
192
|
+
// For 'ice-restart', the manager handles it automatically
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
If the full reconnection doesn't reach `CONNECTED` state within `fullReconnectTimeout` (default: 30 seconds), it's treated as a failed attempt and the next reconnection attempt begins (or `EVENT_RECONNECT_FAILED` is emitted if max attempts reached).
|
|
197
|
+
|
|
164
198
|
## Examples
|
|
165
199
|
|
|
166
200
|
### Basic Usage (Vanilla JavaScript)
|
package/dist/types.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ export interface WebRtcManagerConfig {
|
|
|
26
26
|
maxReconnectAttempts?: number;
|
|
27
27
|
/** Initial reconnection delay in ms. Doubles with each attempt. Defaults to 1000. */
|
|
28
28
|
reconnectDelay?: number;
|
|
29
|
+
/** Timeout in ms for full reconnection strategy to reach connected state. Defaults to 30000. */
|
|
30
|
+
fullReconnectTimeout?: number;
|
|
29
31
|
/**
|
|
30
32
|
* Callback to determine whether reconnection should be attempted.
|
|
31
33
|
* Called before each reconnection attempt when autoReconnect is enabled.
|
package/dist/webrtc-manager.js
CHANGED
|
@@ -89,6 +89,7 @@ export class WebRtcManager {
|
|
|
89
89
|
#dataChannels = new Map();
|
|
90
90
|
#reconnectAttempts = 0;
|
|
91
91
|
#reconnectTimer = null;
|
|
92
|
+
#fullReconnectTimeoutTimer = null;
|
|
92
93
|
#deviceChangeHandler = null;
|
|
93
94
|
/**
|
|
94
95
|
* Creates a new WebRtcManager instance.
|
|
@@ -705,8 +706,12 @@ export class WebRtcManager {
|
|
|
705
706
|
const state = this.#pc.connectionState;
|
|
706
707
|
this.#debug("Connection state changed:", state);
|
|
707
708
|
if (state === "connected") {
|
|
708
|
-
// Connection successful - reset reconnect attempts
|
|
709
|
+
// Connection successful - reset reconnect attempts and clear any pending timeout
|
|
709
710
|
this.#reconnectAttempts = 0;
|
|
711
|
+
if (this.#fullReconnectTimeoutTimer !== null) {
|
|
712
|
+
clearTimeout(this.#fullReconnectTimeoutTimer);
|
|
713
|
+
this.#fullReconnectTimeoutTimer = null;
|
|
714
|
+
}
|
|
710
715
|
this.#dispatch(WebRtcFsmEvent.CONNECTED);
|
|
711
716
|
}
|
|
712
717
|
else if (state === "failed") {
|
|
@@ -747,6 +752,11 @@ export class WebRtcManager {
|
|
|
747
752
|
clearTimeout(this.#reconnectTimer);
|
|
748
753
|
this.#reconnectTimer = null;
|
|
749
754
|
}
|
|
755
|
+
// Clear any pending full reconnection timeout
|
|
756
|
+
if (this.#fullReconnectTimeoutTimer !== null) {
|
|
757
|
+
clearTimeout(this.#fullReconnectTimeoutTimer);
|
|
758
|
+
this.#fullReconnectTimeoutTimer = null;
|
|
759
|
+
}
|
|
750
760
|
// Remove device change listener
|
|
751
761
|
if (this.#deviceChangeHandler) {
|
|
752
762
|
navigator.mediaDevices.removeEventListener("devicechange", this.#deviceChangeHandler);
|
|
@@ -853,8 +863,21 @@ export class WebRtcManager {
|
|
|
853
863
|
// perform the signaling handshake (create offer/answer exchange) to
|
|
854
864
|
// complete the reconnection.
|
|
855
865
|
try {
|
|
866
|
+
// Clean up old connection and reset to IDLE so connect() creates a new PC
|
|
867
|
+
this.#cleanup();
|
|
868
|
+
this.#dispatch(WebRtcFsmEvent.RESET);
|
|
856
869
|
await this.connect();
|
|
857
|
-
//
|
|
870
|
+
// Start timeout for full reconnection - if connection doesn't succeed
|
|
871
|
+
// within the timeout, treat it as a failure
|
|
872
|
+
const timeout = this.#config.fullReconnectTimeout ?? 30000;
|
|
873
|
+
this.#fullReconnectTimeoutTimer = setTimeout(() => {
|
|
874
|
+
this.#fullReconnectTimeoutTimer = null;
|
|
875
|
+
// Only trigger failure if still not connected
|
|
876
|
+
if (this.state !== WebRtcState.CONNECTED) {
|
|
877
|
+
this.#debug("Full reconnection timeout reached, connection not established");
|
|
878
|
+
this.#handleConnectionFailure();
|
|
879
|
+
}
|
|
880
|
+
}, timeout);
|
|
858
881
|
}
|
|
859
882
|
catch (e) {
|
|
860
883
|
this.#logger.error("[WebRtcManager] Reconnection failed:", e);
|