@whereby.com/media 2.8.0 → 2.8.2

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/index.cjs CHANGED
@@ -1562,16 +1562,60 @@ class ReconnectManager extends EventEmitter {
1562
1562
  }
1563
1563
  }
1564
1564
 
1565
+ const DISCONNECT_DURATION_LIMIT_MS$1 = 60000;
1566
+ const SIGNAL_PING_INTERVAL = 2000;
1567
+ const SIGNAL_PING_MAX_LATENCY = 1000;
1568
+ class KeepAliveManager {
1569
+ constructor(serverSocket) {
1570
+ this.lastPingTimestamp = Date.now();
1571
+ this._disconnectDurationLimitEnabled = false;
1572
+ this.disconnectDurationLimitExceeded = false;
1573
+ this.serverSocket = serverSocket;
1574
+ this.serverSocket.on("connect", () => this.onConnect());
1575
+ this.serverSocket.onEngineEvent("ping", () => this.onPing());
1576
+ this.serverSocket.on("disconnect", () => this.onDisconnect());
1577
+ this.serverSocket.onEngineEvent("reconnect_attempt", () => this.onReconnectAttempt());
1578
+ }
1579
+ enableDisconnectDurationLimit() {
1580
+ this._disconnectDurationLimitEnabled = true;
1581
+ }
1582
+ pingHeartbeat() {
1583
+ clearTimeout(this.pingTimer);
1584
+ this.pingTimer = setTimeout(() => {
1585
+ this.serverSocket._socket.io.engine.close();
1586
+ }, SIGNAL_PING_INTERVAL + SIGNAL_PING_MAX_LATENCY);
1587
+ this.lastPingTimestamp = Date.now();
1588
+ }
1589
+ onConnect() {
1590
+ this.pingHeartbeat();
1591
+ }
1592
+ onPing() {
1593
+ this.pingHeartbeat();
1594
+ }
1595
+ onDisconnect() {
1596
+ clearTimeout(this.pingTimer);
1597
+ }
1598
+ onReconnectAttempt() {
1599
+ if (this._disconnectDurationLimitEnabled) {
1600
+ this.disconnectDurationLimitExceeded = Boolean(Date.now() - this.lastPingTimestamp > DISCONNECT_DURATION_LIMIT_MS$1);
1601
+ if (this.disconnectDurationLimitExceeded) {
1602
+ this.serverSocket.disconnect();
1603
+ }
1604
+ }
1605
+ }
1606
+ }
1607
+
1565
1608
  var _a$6;
1566
1609
  const adapter$6 = (_a$6 = adapterRaw.default) !== null && _a$6 !== void 0 ? _a$6 : adapterRaw;
1567
1610
  const DEFAULT_SOCKET_PATH = "/protocol/socket.io/v4";
1568
1611
  const NOOP_KEEPALIVE_INTERVAL = 2000;
1569
1612
  const DISCONNECT_DURATION_LIMIT_MS = 60000;
1570
1613
  class ServerSocket {
1571
- constructor(hostName, optionsOverrides, glitchFree = false, disconnectDurationLimitOn = false) {
1614
+ constructor(hostName, optionsOverrides, glitchFree = false, disconnectDurationLimitOn = false, serverSideDisconnectDurationLimitOn = false) {
1572
1615
  this._wasConnectedUsingWebsocket = false;
1573
- this._disconnectDurationLimitOn = disconnectDurationLimitOn;
1574
- this.disconnectDurationLimitExceeded = false;
1616
+ this._disconnectDurationLimitOn = disconnectDurationLimitOn && !serverSideDisconnectDurationLimitOn;
1617
+ this._serverSideDisconnectDurationLimitOn = serverSideDisconnectDurationLimitOn;
1618
+ this._disconnectDurationLimitExceeded = false;
1575
1619
  this._reconnectManager = null;
1576
1620
  this._socket = socket_ioClient.io(hostName, Object.assign({ path: DEFAULT_SOCKET_PATH, randomizationFactor: 0.5, reconnectionDelay: 250, reconnectionDelayMax: 5000, timeout: 5000, transports: ["websocket"], withCredentials: true }, optionsOverrides));
1577
1621
  this._disconnectDurationLimitEnabled = false;
@@ -1580,7 +1624,7 @@ class ServerSocket {
1580
1624
  if (this._disconnectDurationLimitOn &&
1581
1625
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1582
1626
  this._socket.close();
1583
- this.disconnectDurationLimitExceeded = true;
1627
+ this._disconnectDurationLimitExceeded = true;
1584
1628
  }
1585
1629
  this._socket.sendBuffer = [];
1586
1630
  });
@@ -1589,7 +1633,7 @@ class ServerSocket {
1589
1633
  if (this._disconnectDurationLimitOn &&
1590
1634
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1591
1635
  this._socket.close();
1592
- this.disconnectDurationLimitExceeded = true;
1636
+ this._disconnectDurationLimitExceeded = true;
1593
1637
  }
1594
1638
  if (this._wasConnectedUsingWebsocket) {
1595
1639
  this._socket.io.opts.transports = ["websocket"];
@@ -1603,6 +1647,8 @@ class ServerSocket {
1603
1647
  });
1604
1648
  if (glitchFree)
1605
1649
  this._reconnectManager = new ReconnectManager(this._socket);
1650
+ if (this._serverSideDisconnectDurationLimitOn)
1651
+ this._keepAliveManager = new KeepAliveManager(this);
1606
1652
  this._socket.on("room_joined", (payload) => {
1607
1653
  const { error } = payload;
1608
1654
  if (!error) {
@@ -1613,6 +1659,8 @@ class ServerSocket {
1613
1659
  const transport = this.getTransport();
1614
1660
  if (transport === "websocket") {
1615
1661
  this._wasConnectedUsingWebsocket = true;
1662
+ if (this._serverSideDisconnectDurationLimitOn)
1663
+ return;
1616
1664
  if (!this.noopKeepaliveInterval) {
1617
1665
  let disconnectDurationLimitTimestampCandidate = Date.now();
1618
1666
  this.noopKeepaliveInterval = setInterval(() => {
@@ -1633,13 +1681,15 @@ class ServerSocket {
1633
1681
  }
1634
1682
  });
1635
1683
  this._socket.on("disconnect", () => {
1684
+ this.joinRoomFinished = false;
1685
+ this.disconnectTimestamp = Date.now();
1686
+ if (this._serverSideDisconnectDurationLimitOn)
1687
+ return;
1636
1688
  if (this._disconnectDurationLimitOn &&
1637
1689
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1638
1690
  this._socket.close();
1639
- this.disconnectDurationLimitExceeded = true;
1691
+ this._disconnectDurationLimitExceeded = true;
1640
1692
  }
1641
- this.joinRoomFinished = false;
1642
- this.disconnectTimestamp = Date.now();
1643
1693
  if (this.noopKeepaliveInterval) {
1644
1694
  clearInterval(this.noopKeepaliveInterval);
1645
1695
  this.noopKeepaliveInterval = null;
@@ -1655,8 +1705,22 @@ class ServerSocket {
1655
1705
  }
1656
1706
  return false;
1657
1707
  }
1708
+ get disconnectDurationLimitExceeded() {
1709
+ var _a, _b;
1710
+ if (this._serverSideDisconnectDurationLimitOn) {
1711
+ return (_b = (_a = this._keepAliveManager) === null || _a === void 0 ? void 0 : _a.disconnectDurationLimitExceeded) !== null && _b !== void 0 ? _b : false;
1712
+ }
1713
+ else if (this._disconnectDurationLimitOn) {
1714
+ return this._disconnectDurationLimitExceeded;
1715
+ }
1716
+ return false;
1717
+ }
1658
1718
  enableDisconnectDurationLimit() {
1659
- if (this._disconnectDurationLimitOn) {
1719
+ var _a;
1720
+ if (this._serverSideDisconnectDurationLimitOn) {
1721
+ (_a = this._keepAliveManager) === null || _a === void 0 ? void 0 : _a.enableDisconnectDurationLimit();
1722
+ }
1723
+ else if (this._disconnectDurationLimitOn) {
1660
1724
  this._disconnectDurationLimitEnabled = true;
1661
1725
  }
1662
1726
  }
@@ -2665,6 +2729,7 @@ class P2pRtcManager {
2665
2729
  P2PReplaceTrackWithoutPC: 0,
2666
2730
  P2PReplaceTrackSourceKindNotFound: 0,
2667
2731
  P2PRemoveStreamNoPC: 0,
2732
+ P2POnTrackNoStream: 0,
2668
2733
  };
2669
2734
  }
2670
2735
  numberOfPeerconnections() {
@@ -3026,7 +3091,12 @@ class P2pRtcManager {
3026
3091
  const { pc } = session;
3027
3092
  pc.ontrack = (event) => {
3028
3093
  const stream = event.streams[0];
3029
- if (stream.id === "default" && stream.getAudioTracks().length === 0) {
3094
+ if (!stream) {
3095
+ this.analytics.P2POnTrackNoStream++;
3096
+ rtcStats.sendEvent("P2POnTrackNoStream", {
3097
+ trackKind: event.track.kind,
3098
+ trackId: event.track.id
3099
+ });
3030
3100
  return;
3031
3101
  }
3032
3102
  if (session.streamIds.indexOf(stream.id) === -1) {
@@ -3035,16 +3105,6 @@ class P2pRtcManager {
3035
3105
  clientId,
3036
3106
  stream,
3037
3107
  });
3038
- if (session.connectionStatus === TYPES.CONNECTION_SUCCESSFUL) {
3039
- setTimeout(() => {
3040
- this._emit(EVENTS.CLIENT_CONNECTION_STATUS_CHANGED, {
3041
- streamIds: session.streamIds,
3042
- clientId,
3043
- status: session.connectionStatus,
3044
- previous: TYPES.CONNECTING,
3045
- });
3046
- }, 0);
3047
- }
3048
3108
  }
3049
3109
  };
3050
3110
  pc.oniceconnectionstatechange = () => {
package/dist/index.d.cts CHANGED
@@ -705,20 +705,38 @@ declare class ReconnectManager extends EventEmitter {
705
705
  _resetClientState(payload: any): void;
706
706
  }
707
707
 
708
+ declare class KeepAliveManager {
709
+ private serverSocket;
710
+ private pingTimer;
711
+ lastPingTimestamp: number;
712
+ private _disconnectDurationLimitEnabled;
713
+ disconnectDurationLimitExceeded: boolean;
714
+ constructor(serverSocket: ServerSocket);
715
+ enableDisconnectDurationLimit(): void;
716
+ private pingHeartbeat;
717
+ private onConnect;
718
+ private onPing;
719
+ private onDisconnect;
720
+ private onReconnectAttempt;
721
+ }
722
+
708
723
  declare class ServerSocket {
709
724
  _socket: any;
710
725
  _reconnectManager?: ReconnectManager | null;
726
+ _keepAliveManager?: KeepAliveManager | null;
711
727
  noopKeepaliveInterval: any;
712
728
  _wasConnectedUsingWebsocket?: boolean;
713
729
  disconnectTimestamp: number | undefined;
714
- disconnectDurationLimitExceeded: boolean;
730
+ _disconnectDurationLimitExceeded: boolean;
715
731
  joinRoomFinished: boolean;
732
+ _serverSideDisconnectDurationLimitOn: boolean;
716
733
  _disconnectDurationLimitOn: boolean;
717
734
  _disconnectDurationLimitEnabled: boolean;
718
735
  _disconnectDurationLimitInMs: number | undefined;
719
736
  _disconnectDurationLimitLatestTimestamp: number | undefined;
720
- constructor(hostName: string, optionsOverrides?: any, glitchFree?: boolean, disconnectDurationLimitOn?: boolean);
737
+ constructor(hostName: string, optionsOverrides?: any, glitchFree?: boolean, disconnectDurationLimitOn?: boolean, serverSideDisconnectDurationLimitOn?: boolean);
721
738
  _didExceedDisconnectDurationLimit(timestamp: number | undefined): boolean;
739
+ get disconnectDurationLimitExceeded(): boolean;
722
740
  enableDisconnectDurationLimit(): void;
723
741
  setRtcManager(rtcManager?: RtcManager): void;
724
742
  connect(): void;
@@ -1191,6 +1209,7 @@ type P2PAnalytics = {
1191
1209
  P2PReplaceTrackWithoutPC: number;
1192
1210
  P2PReplaceTrackSourceKindNotFound: number;
1193
1211
  P2PRemoveStreamNoPC: number;
1212
+ P2POnTrackNoStream: number;
1194
1213
  };
1195
1214
  type P2PAnalyticMetric = keyof P2PAnalytics;
1196
1215
  type P2PIncrementAnalyticMetric = (metric: P2PAnalyticMetric) => void;
package/dist/index.d.mts CHANGED
@@ -705,20 +705,38 @@ declare class ReconnectManager extends EventEmitter {
705
705
  _resetClientState(payload: any): void;
706
706
  }
707
707
 
708
+ declare class KeepAliveManager {
709
+ private serverSocket;
710
+ private pingTimer;
711
+ lastPingTimestamp: number;
712
+ private _disconnectDurationLimitEnabled;
713
+ disconnectDurationLimitExceeded: boolean;
714
+ constructor(serverSocket: ServerSocket);
715
+ enableDisconnectDurationLimit(): void;
716
+ private pingHeartbeat;
717
+ private onConnect;
718
+ private onPing;
719
+ private onDisconnect;
720
+ private onReconnectAttempt;
721
+ }
722
+
708
723
  declare class ServerSocket {
709
724
  _socket: any;
710
725
  _reconnectManager?: ReconnectManager | null;
726
+ _keepAliveManager?: KeepAliveManager | null;
711
727
  noopKeepaliveInterval: any;
712
728
  _wasConnectedUsingWebsocket?: boolean;
713
729
  disconnectTimestamp: number | undefined;
714
- disconnectDurationLimitExceeded: boolean;
730
+ _disconnectDurationLimitExceeded: boolean;
715
731
  joinRoomFinished: boolean;
732
+ _serverSideDisconnectDurationLimitOn: boolean;
716
733
  _disconnectDurationLimitOn: boolean;
717
734
  _disconnectDurationLimitEnabled: boolean;
718
735
  _disconnectDurationLimitInMs: number | undefined;
719
736
  _disconnectDurationLimitLatestTimestamp: number | undefined;
720
- constructor(hostName: string, optionsOverrides?: any, glitchFree?: boolean, disconnectDurationLimitOn?: boolean);
737
+ constructor(hostName: string, optionsOverrides?: any, glitchFree?: boolean, disconnectDurationLimitOn?: boolean, serverSideDisconnectDurationLimitOn?: boolean);
721
738
  _didExceedDisconnectDurationLimit(timestamp: number | undefined): boolean;
739
+ get disconnectDurationLimitExceeded(): boolean;
722
740
  enableDisconnectDurationLimit(): void;
723
741
  setRtcManager(rtcManager?: RtcManager): void;
724
742
  connect(): void;
@@ -1191,6 +1209,7 @@ type P2PAnalytics = {
1191
1209
  P2PReplaceTrackWithoutPC: number;
1192
1210
  P2PReplaceTrackSourceKindNotFound: number;
1193
1211
  P2PRemoveStreamNoPC: number;
1212
+ P2POnTrackNoStream: number;
1194
1213
  };
1195
1214
  type P2PAnalyticMetric = keyof P2PAnalytics;
1196
1215
  type P2PIncrementAnalyticMetric = (metric: P2PAnalyticMetric) => void;
package/dist/index.d.ts CHANGED
@@ -705,20 +705,38 @@ declare class ReconnectManager extends EventEmitter {
705
705
  _resetClientState(payload: any): void;
706
706
  }
707
707
 
708
+ declare class KeepAliveManager {
709
+ private serverSocket;
710
+ private pingTimer;
711
+ lastPingTimestamp: number;
712
+ private _disconnectDurationLimitEnabled;
713
+ disconnectDurationLimitExceeded: boolean;
714
+ constructor(serverSocket: ServerSocket);
715
+ enableDisconnectDurationLimit(): void;
716
+ private pingHeartbeat;
717
+ private onConnect;
718
+ private onPing;
719
+ private onDisconnect;
720
+ private onReconnectAttempt;
721
+ }
722
+
708
723
  declare class ServerSocket {
709
724
  _socket: any;
710
725
  _reconnectManager?: ReconnectManager | null;
726
+ _keepAliveManager?: KeepAliveManager | null;
711
727
  noopKeepaliveInterval: any;
712
728
  _wasConnectedUsingWebsocket?: boolean;
713
729
  disconnectTimestamp: number | undefined;
714
- disconnectDurationLimitExceeded: boolean;
730
+ _disconnectDurationLimitExceeded: boolean;
715
731
  joinRoomFinished: boolean;
732
+ _serverSideDisconnectDurationLimitOn: boolean;
716
733
  _disconnectDurationLimitOn: boolean;
717
734
  _disconnectDurationLimitEnabled: boolean;
718
735
  _disconnectDurationLimitInMs: number | undefined;
719
736
  _disconnectDurationLimitLatestTimestamp: number | undefined;
720
- constructor(hostName: string, optionsOverrides?: any, glitchFree?: boolean, disconnectDurationLimitOn?: boolean);
737
+ constructor(hostName: string, optionsOverrides?: any, glitchFree?: boolean, disconnectDurationLimitOn?: boolean, serverSideDisconnectDurationLimitOn?: boolean);
721
738
  _didExceedDisconnectDurationLimit(timestamp: number | undefined): boolean;
739
+ get disconnectDurationLimitExceeded(): boolean;
722
740
  enableDisconnectDurationLimit(): void;
723
741
  setRtcManager(rtcManager?: RtcManager): void;
724
742
  connect(): void;
@@ -1191,6 +1209,7 @@ type P2PAnalytics = {
1191
1209
  P2PReplaceTrackWithoutPC: number;
1192
1210
  P2PReplaceTrackSourceKindNotFound: number;
1193
1211
  P2PRemoveStreamNoPC: number;
1212
+ P2POnTrackNoStream: number;
1194
1213
  };
1195
1214
  type P2PAnalyticMetric = keyof P2PAnalytics;
1196
1215
  type P2PIncrementAnalyticMetric = (metric: P2PAnalyticMetric) => void;
package/dist/index.mjs CHANGED
@@ -1541,16 +1541,60 @@ class ReconnectManager extends EventEmitter {
1541
1541
  }
1542
1542
  }
1543
1543
 
1544
+ const DISCONNECT_DURATION_LIMIT_MS$1 = 60000;
1545
+ const SIGNAL_PING_INTERVAL = 2000;
1546
+ const SIGNAL_PING_MAX_LATENCY = 1000;
1547
+ class KeepAliveManager {
1548
+ constructor(serverSocket) {
1549
+ this.lastPingTimestamp = Date.now();
1550
+ this._disconnectDurationLimitEnabled = false;
1551
+ this.disconnectDurationLimitExceeded = false;
1552
+ this.serverSocket = serverSocket;
1553
+ this.serverSocket.on("connect", () => this.onConnect());
1554
+ this.serverSocket.onEngineEvent("ping", () => this.onPing());
1555
+ this.serverSocket.on("disconnect", () => this.onDisconnect());
1556
+ this.serverSocket.onEngineEvent("reconnect_attempt", () => this.onReconnectAttempt());
1557
+ }
1558
+ enableDisconnectDurationLimit() {
1559
+ this._disconnectDurationLimitEnabled = true;
1560
+ }
1561
+ pingHeartbeat() {
1562
+ clearTimeout(this.pingTimer);
1563
+ this.pingTimer = setTimeout(() => {
1564
+ this.serverSocket._socket.io.engine.close();
1565
+ }, SIGNAL_PING_INTERVAL + SIGNAL_PING_MAX_LATENCY);
1566
+ this.lastPingTimestamp = Date.now();
1567
+ }
1568
+ onConnect() {
1569
+ this.pingHeartbeat();
1570
+ }
1571
+ onPing() {
1572
+ this.pingHeartbeat();
1573
+ }
1574
+ onDisconnect() {
1575
+ clearTimeout(this.pingTimer);
1576
+ }
1577
+ onReconnectAttempt() {
1578
+ if (this._disconnectDurationLimitEnabled) {
1579
+ this.disconnectDurationLimitExceeded = Boolean(Date.now() - this.lastPingTimestamp > DISCONNECT_DURATION_LIMIT_MS$1);
1580
+ if (this.disconnectDurationLimitExceeded) {
1581
+ this.serverSocket.disconnect();
1582
+ }
1583
+ }
1584
+ }
1585
+ }
1586
+
1544
1587
  var _a$6;
1545
1588
  const adapter$6 = (_a$6 = adapterRaw.default) !== null && _a$6 !== void 0 ? _a$6 : adapterRaw;
1546
1589
  const DEFAULT_SOCKET_PATH = "/protocol/socket.io/v4";
1547
1590
  const NOOP_KEEPALIVE_INTERVAL = 2000;
1548
1591
  const DISCONNECT_DURATION_LIMIT_MS = 60000;
1549
1592
  class ServerSocket {
1550
- constructor(hostName, optionsOverrides, glitchFree = false, disconnectDurationLimitOn = false) {
1593
+ constructor(hostName, optionsOverrides, glitchFree = false, disconnectDurationLimitOn = false, serverSideDisconnectDurationLimitOn = false) {
1551
1594
  this._wasConnectedUsingWebsocket = false;
1552
- this._disconnectDurationLimitOn = disconnectDurationLimitOn;
1553
- this.disconnectDurationLimitExceeded = false;
1595
+ this._disconnectDurationLimitOn = disconnectDurationLimitOn && !serverSideDisconnectDurationLimitOn;
1596
+ this._serverSideDisconnectDurationLimitOn = serverSideDisconnectDurationLimitOn;
1597
+ this._disconnectDurationLimitExceeded = false;
1554
1598
  this._reconnectManager = null;
1555
1599
  this._socket = io(hostName, Object.assign({ path: DEFAULT_SOCKET_PATH, randomizationFactor: 0.5, reconnectionDelay: 250, reconnectionDelayMax: 5000, timeout: 5000, transports: ["websocket"], withCredentials: true }, optionsOverrides));
1556
1600
  this._disconnectDurationLimitEnabled = false;
@@ -1559,7 +1603,7 @@ class ServerSocket {
1559
1603
  if (this._disconnectDurationLimitOn &&
1560
1604
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1561
1605
  this._socket.close();
1562
- this.disconnectDurationLimitExceeded = true;
1606
+ this._disconnectDurationLimitExceeded = true;
1563
1607
  }
1564
1608
  this._socket.sendBuffer = [];
1565
1609
  });
@@ -1568,7 +1612,7 @@ class ServerSocket {
1568
1612
  if (this._disconnectDurationLimitOn &&
1569
1613
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1570
1614
  this._socket.close();
1571
- this.disconnectDurationLimitExceeded = true;
1615
+ this._disconnectDurationLimitExceeded = true;
1572
1616
  }
1573
1617
  if (this._wasConnectedUsingWebsocket) {
1574
1618
  this._socket.io.opts.transports = ["websocket"];
@@ -1582,6 +1626,8 @@ class ServerSocket {
1582
1626
  });
1583
1627
  if (glitchFree)
1584
1628
  this._reconnectManager = new ReconnectManager(this._socket);
1629
+ if (this._serverSideDisconnectDurationLimitOn)
1630
+ this._keepAliveManager = new KeepAliveManager(this);
1585
1631
  this._socket.on("room_joined", (payload) => {
1586
1632
  const { error } = payload;
1587
1633
  if (!error) {
@@ -1592,6 +1638,8 @@ class ServerSocket {
1592
1638
  const transport = this.getTransport();
1593
1639
  if (transport === "websocket") {
1594
1640
  this._wasConnectedUsingWebsocket = true;
1641
+ if (this._serverSideDisconnectDurationLimitOn)
1642
+ return;
1595
1643
  if (!this.noopKeepaliveInterval) {
1596
1644
  let disconnectDurationLimitTimestampCandidate = Date.now();
1597
1645
  this.noopKeepaliveInterval = setInterval(() => {
@@ -1612,13 +1660,15 @@ class ServerSocket {
1612
1660
  }
1613
1661
  });
1614
1662
  this._socket.on("disconnect", () => {
1663
+ this.joinRoomFinished = false;
1664
+ this.disconnectTimestamp = Date.now();
1665
+ if (this._serverSideDisconnectDurationLimitOn)
1666
+ return;
1615
1667
  if (this._disconnectDurationLimitOn &&
1616
1668
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1617
1669
  this._socket.close();
1618
- this.disconnectDurationLimitExceeded = true;
1670
+ this._disconnectDurationLimitExceeded = true;
1619
1671
  }
1620
- this.joinRoomFinished = false;
1621
- this.disconnectTimestamp = Date.now();
1622
1672
  if (this.noopKeepaliveInterval) {
1623
1673
  clearInterval(this.noopKeepaliveInterval);
1624
1674
  this.noopKeepaliveInterval = null;
@@ -1634,8 +1684,22 @@ class ServerSocket {
1634
1684
  }
1635
1685
  return false;
1636
1686
  }
1687
+ get disconnectDurationLimitExceeded() {
1688
+ var _a, _b;
1689
+ if (this._serverSideDisconnectDurationLimitOn) {
1690
+ return (_b = (_a = this._keepAliveManager) === null || _a === void 0 ? void 0 : _a.disconnectDurationLimitExceeded) !== null && _b !== void 0 ? _b : false;
1691
+ }
1692
+ else if (this._disconnectDurationLimitOn) {
1693
+ return this._disconnectDurationLimitExceeded;
1694
+ }
1695
+ return false;
1696
+ }
1637
1697
  enableDisconnectDurationLimit() {
1638
- if (this._disconnectDurationLimitOn) {
1698
+ var _a;
1699
+ if (this._serverSideDisconnectDurationLimitOn) {
1700
+ (_a = this._keepAliveManager) === null || _a === void 0 ? void 0 : _a.enableDisconnectDurationLimit();
1701
+ }
1702
+ else if (this._disconnectDurationLimitOn) {
1639
1703
  this._disconnectDurationLimitEnabled = true;
1640
1704
  }
1641
1705
  }
@@ -2644,6 +2708,7 @@ class P2pRtcManager {
2644
2708
  P2PReplaceTrackWithoutPC: 0,
2645
2709
  P2PReplaceTrackSourceKindNotFound: 0,
2646
2710
  P2PRemoveStreamNoPC: 0,
2711
+ P2POnTrackNoStream: 0,
2647
2712
  };
2648
2713
  }
2649
2714
  numberOfPeerconnections() {
@@ -3005,7 +3070,12 @@ class P2pRtcManager {
3005
3070
  const { pc } = session;
3006
3071
  pc.ontrack = (event) => {
3007
3072
  const stream = event.streams[0];
3008
- if (stream.id === "default" && stream.getAudioTracks().length === 0) {
3073
+ if (!stream) {
3074
+ this.analytics.P2POnTrackNoStream++;
3075
+ rtcStats.sendEvent("P2POnTrackNoStream", {
3076
+ trackKind: event.track.kind,
3077
+ trackId: event.track.id
3078
+ });
3009
3079
  return;
3010
3080
  }
3011
3081
  if (session.streamIds.indexOf(stream.id) === -1) {
@@ -3014,16 +3084,6 @@ class P2pRtcManager {
3014
3084
  clientId,
3015
3085
  stream,
3016
3086
  });
3017
- if (session.connectionStatus === TYPES.CONNECTION_SUCCESSFUL) {
3018
- setTimeout(() => {
3019
- this._emit(EVENTS.CLIENT_CONNECTION_STATUS_CHANGED, {
3020
- streamIds: session.streamIds,
3021
- clientId,
3022
- status: session.connectionStatus,
3023
- previous: TYPES.CONNECTING,
3024
- });
3025
- }, 0);
3026
- }
3027
3087
  }
3028
3088
  };
3029
3089
  pc.oniceconnectionstatechange = () => {
@@ -1541,16 +1541,60 @@ class ReconnectManager extends EventEmitter {
1541
1541
  }
1542
1542
  }
1543
1543
 
1544
+ const DISCONNECT_DURATION_LIMIT_MS$1 = 60000;
1545
+ const SIGNAL_PING_INTERVAL = 2000;
1546
+ const SIGNAL_PING_MAX_LATENCY = 1000;
1547
+ class KeepAliveManager {
1548
+ constructor(serverSocket) {
1549
+ this.lastPingTimestamp = Date.now();
1550
+ this._disconnectDurationLimitEnabled = false;
1551
+ this.disconnectDurationLimitExceeded = false;
1552
+ this.serverSocket = serverSocket;
1553
+ this.serverSocket.on("connect", () => this.onConnect());
1554
+ this.serverSocket.onEngineEvent("ping", () => this.onPing());
1555
+ this.serverSocket.on("disconnect", () => this.onDisconnect());
1556
+ this.serverSocket.onEngineEvent("reconnect_attempt", () => this.onReconnectAttempt());
1557
+ }
1558
+ enableDisconnectDurationLimit() {
1559
+ this._disconnectDurationLimitEnabled = true;
1560
+ }
1561
+ pingHeartbeat() {
1562
+ clearTimeout(this.pingTimer);
1563
+ this.pingTimer = setTimeout(() => {
1564
+ this.serverSocket._socket.io.engine.close();
1565
+ }, SIGNAL_PING_INTERVAL + SIGNAL_PING_MAX_LATENCY);
1566
+ this.lastPingTimestamp = Date.now();
1567
+ }
1568
+ onConnect() {
1569
+ this.pingHeartbeat();
1570
+ }
1571
+ onPing() {
1572
+ this.pingHeartbeat();
1573
+ }
1574
+ onDisconnect() {
1575
+ clearTimeout(this.pingTimer);
1576
+ }
1577
+ onReconnectAttempt() {
1578
+ if (this._disconnectDurationLimitEnabled) {
1579
+ this.disconnectDurationLimitExceeded = Boolean(Date.now() - this.lastPingTimestamp > DISCONNECT_DURATION_LIMIT_MS$1);
1580
+ if (this.disconnectDurationLimitExceeded) {
1581
+ this.serverSocket.disconnect();
1582
+ }
1583
+ }
1584
+ }
1585
+ }
1586
+
1544
1587
  var _a$6;
1545
1588
  const adapter$6 = (_a$6 = adapterRaw.default) !== null && _a$6 !== void 0 ? _a$6 : adapterRaw;
1546
1589
  const DEFAULT_SOCKET_PATH = "/protocol/socket.io/v4";
1547
1590
  const NOOP_KEEPALIVE_INTERVAL = 2000;
1548
1591
  const DISCONNECT_DURATION_LIMIT_MS = 60000;
1549
1592
  class ServerSocket {
1550
- constructor(hostName, optionsOverrides, glitchFree = false, disconnectDurationLimitOn = false) {
1593
+ constructor(hostName, optionsOverrides, glitchFree = false, disconnectDurationLimitOn = false, serverSideDisconnectDurationLimitOn = false) {
1551
1594
  this._wasConnectedUsingWebsocket = false;
1552
- this._disconnectDurationLimitOn = disconnectDurationLimitOn;
1553
- this.disconnectDurationLimitExceeded = false;
1595
+ this._disconnectDurationLimitOn = disconnectDurationLimitOn && !serverSideDisconnectDurationLimitOn;
1596
+ this._serverSideDisconnectDurationLimitOn = serverSideDisconnectDurationLimitOn;
1597
+ this._disconnectDurationLimitExceeded = false;
1554
1598
  this._reconnectManager = null;
1555
1599
  this._socket = io(hostName, Object.assign({ path: DEFAULT_SOCKET_PATH, randomizationFactor: 0.5, reconnectionDelay: 250, reconnectionDelayMax: 5000, timeout: 5000, transports: ["websocket"], withCredentials: true }, optionsOverrides));
1556
1600
  this._disconnectDurationLimitEnabled = false;
@@ -1559,7 +1603,7 @@ class ServerSocket {
1559
1603
  if (this._disconnectDurationLimitOn &&
1560
1604
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1561
1605
  this._socket.close();
1562
- this.disconnectDurationLimitExceeded = true;
1606
+ this._disconnectDurationLimitExceeded = true;
1563
1607
  }
1564
1608
  this._socket.sendBuffer = [];
1565
1609
  });
@@ -1568,7 +1612,7 @@ class ServerSocket {
1568
1612
  if (this._disconnectDurationLimitOn &&
1569
1613
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1570
1614
  this._socket.close();
1571
- this.disconnectDurationLimitExceeded = true;
1615
+ this._disconnectDurationLimitExceeded = true;
1572
1616
  }
1573
1617
  if (this._wasConnectedUsingWebsocket) {
1574
1618
  this._socket.io.opts.transports = ["websocket"];
@@ -1582,6 +1626,8 @@ class ServerSocket {
1582
1626
  });
1583
1627
  if (glitchFree)
1584
1628
  this._reconnectManager = new ReconnectManager(this._socket);
1629
+ if (this._serverSideDisconnectDurationLimitOn)
1630
+ this._keepAliveManager = new KeepAliveManager(this);
1585
1631
  this._socket.on("room_joined", (payload) => {
1586
1632
  const { error } = payload;
1587
1633
  if (!error) {
@@ -1592,6 +1638,8 @@ class ServerSocket {
1592
1638
  const transport = this.getTransport();
1593
1639
  if (transport === "websocket") {
1594
1640
  this._wasConnectedUsingWebsocket = true;
1641
+ if (this._serverSideDisconnectDurationLimitOn)
1642
+ return;
1595
1643
  if (!this.noopKeepaliveInterval) {
1596
1644
  let disconnectDurationLimitTimestampCandidate = Date.now();
1597
1645
  this.noopKeepaliveInterval = setInterval(() => {
@@ -1612,13 +1660,15 @@ class ServerSocket {
1612
1660
  }
1613
1661
  });
1614
1662
  this._socket.on("disconnect", () => {
1663
+ this.joinRoomFinished = false;
1664
+ this.disconnectTimestamp = Date.now();
1665
+ if (this._serverSideDisconnectDurationLimitOn)
1666
+ return;
1615
1667
  if (this._disconnectDurationLimitOn &&
1616
1668
  this._didExceedDisconnectDurationLimit(this._disconnectDurationLimitLatestTimestamp)) {
1617
1669
  this._socket.close();
1618
- this.disconnectDurationLimitExceeded = true;
1670
+ this._disconnectDurationLimitExceeded = true;
1619
1671
  }
1620
- this.joinRoomFinished = false;
1621
- this.disconnectTimestamp = Date.now();
1622
1672
  if (this.noopKeepaliveInterval) {
1623
1673
  clearInterval(this.noopKeepaliveInterval);
1624
1674
  this.noopKeepaliveInterval = null;
@@ -1634,8 +1684,22 @@ class ServerSocket {
1634
1684
  }
1635
1685
  return false;
1636
1686
  }
1687
+ get disconnectDurationLimitExceeded() {
1688
+ var _a, _b;
1689
+ if (this._serverSideDisconnectDurationLimitOn) {
1690
+ return (_b = (_a = this._keepAliveManager) === null || _a === void 0 ? void 0 : _a.disconnectDurationLimitExceeded) !== null && _b !== void 0 ? _b : false;
1691
+ }
1692
+ else if (this._disconnectDurationLimitOn) {
1693
+ return this._disconnectDurationLimitExceeded;
1694
+ }
1695
+ return false;
1696
+ }
1637
1697
  enableDisconnectDurationLimit() {
1638
- if (this._disconnectDurationLimitOn) {
1698
+ var _a;
1699
+ if (this._serverSideDisconnectDurationLimitOn) {
1700
+ (_a = this._keepAliveManager) === null || _a === void 0 ? void 0 : _a.enableDisconnectDurationLimit();
1701
+ }
1702
+ else if (this._disconnectDurationLimitOn) {
1639
1703
  this._disconnectDurationLimitEnabled = true;
1640
1704
  }
1641
1705
  }
@@ -2644,6 +2708,7 @@ class P2pRtcManager {
2644
2708
  P2PReplaceTrackWithoutPC: 0,
2645
2709
  P2PReplaceTrackSourceKindNotFound: 0,
2646
2710
  P2PRemoveStreamNoPC: 0,
2711
+ P2POnTrackNoStream: 0,
2647
2712
  };
2648
2713
  }
2649
2714
  numberOfPeerconnections() {
@@ -3005,7 +3070,12 @@ class P2pRtcManager {
3005
3070
  const { pc } = session;
3006
3071
  pc.ontrack = (event) => {
3007
3072
  const stream = event.streams[0];
3008
- if (stream.id === "default" && stream.getAudioTracks().length === 0) {
3073
+ if (!stream) {
3074
+ this.analytics.P2POnTrackNoStream++;
3075
+ rtcStats.sendEvent("P2POnTrackNoStream", {
3076
+ trackKind: event.track.kind,
3077
+ trackId: event.track.id
3078
+ });
3009
3079
  return;
3010
3080
  }
3011
3081
  if (session.streamIds.indexOf(stream.id) === -1) {
@@ -3014,16 +3084,6 @@ class P2pRtcManager {
3014
3084
  clientId,
3015
3085
  stream,
3016
3086
  });
3017
- if (session.connectionStatus === TYPES.CONNECTION_SUCCESSFUL) {
3018
- setTimeout(() => {
3019
- this._emit(EVENTS.CLIENT_CONNECTION_STATUS_CHANGED, {
3020
- streamIds: session.streamIds,
3021
- clientId,
3022
- status: session.connectionStatus,
3023
- previous: TYPES.CONNECTING,
3024
- });
3025
- }, 0);
3026
- }
3027
3087
  }
3028
3088
  };
3029
3089
  pc.oniceconnectionstatechange = () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@whereby.com/media",
3
3
  "description": "Media library for Whereby",
4
- "version": "2.8.0",
4
+ "version": "2.8.2",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/whereby/sdk",
7
7
  "repository": {