@apocaliss92/nodelink-js 0.5.1-beta.8 → 0.5.1-beta.9

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
@@ -41759,6 +41759,20 @@ var import_node_events15 = require("events");
41759
41759
  var net6 = __toESM(require("net"), 1);
41760
41760
  var crypto3 = __toESM(require("crypto"), 1);
41761
41761
  var md5Hex = (s) => crypto3.createHash("md5").update(s).digest("hex");
41762
+ var RTCP_KEEPALIVE_INTERVAL_MS = 1e4;
41763
+ function buildInterleavedRtcpRr(channel, ssrc) {
41764
+ const rtcp = Buffer.alloc(8);
41765
+ rtcp[0] = 128;
41766
+ rtcp[1] = 201;
41767
+ rtcp.writeUInt16BE(1, 2);
41768
+ rtcp.writeUInt32BE(ssrc >>> 0, 4);
41769
+ const frame = Buffer.alloc(4 + rtcp.length);
41770
+ frame[0] = 36;
41771
+ frame[1] = channel & 255;
41772
+ frame.writeUInt16BE(rtcp.length, 2);
41773
+ rtcp.copy(frame, 4);
41774
+ return frame;
41775
+ }
41762
41776
  function normalizePath(path7) {
41763
41777
  if (!path7) return "/";
41764
41778
  let p = path7;
@@ -41955,6 +41969,7 @@ var BaichuanRtspBackchannelServer = class _BaichuanRtspBackchannelServer extends
41955
41969
  this.server = void 0;
41956
41970
  for (const session of this.sessionByClient.values()) {
41957
41971
  this.sessionByClient.delete(session.clientId);
41972
+ this.stopRtcpKeepalive(session);
41958
41973
  if (session.handler) {
41959
41974
  void session.handler.stop();
41960
41975
  }
@@ -41981,6 +41996,7 @@ var BaichuanRtspBackchannelServer = class _BaichuanRtspBackchannelServer extends
41981
41996
  const durationMs = Date.now() - connectedAt;
41982
41997
  if (session) {
41983
41998
  this.sessionByClient.delete(clientId);
41999
+ this.stopRtcpKeepalive(session);
41984
42000
  if (session.handler) {
41985
42001
  const stats = session.handler.stats;
41986
42002
  this.logger.info?.(
@@ -42285,12 +42301,14 @@ ${sdp.trimEnd()}`
42285
42301
  }
42286
42302
  session.handler = handler;
42287
42303
  send(200, "OK", { Session: session.sessionId });
42304
+ this.startRtcpKeepalive(session);
42288
42305
  return;
42289
42306
  }
42290
42307
  case "TEARDOWN": {
42291
42308
  const session = this.sessionByClient.get(clientId);
42292
42309
  if (session) {
42293
42310
  this.sessionByClient.delete(clientId);
42311
+ this.stopRtcpKeepalive(session);
42294
42312
  if (session.handler) {
42295
42313
  const stats = session.handler.stats;
42296
42314
  this.logger.info?.(
@@ -42321,6 +42339,39 @@ ${sdp.trimEnd()}`
42321
42339
  send(501, "Not Implemented");
42322
42340
  }
42323
42341
  }
42342
+ /**
42343
+ * Start emitting an interleaved RTCP RR every
42344
+ * {@link RTCP_KEEPALIVE_INTERVAL_MS}. The RR carries no report blocks —
42345
+ * its purpose is to push *some* bytes back onto the TCP connection so
42346
+ * the producer's read deadline keeps resetting. Idempotent.
42347
+ */
42348
+ startRtcpKeepalive(session) {
42349
+ if (session.rtcpKeepaliveTimer) return;
42350
+ session.rtcpSsrc = Math.floor(Math.random() * 4294967295) >>> 0;
42351
+ const frame = buildInterleavedRtcpRr(session.rtcpChannel, session.rtcpSsrc);
42352
+ const writeOne = () => {
42353
+ if (!session.socket.writable) return;
42354
+ try {
42355
+ session.socket.write(frame);
42356
+ } catch (e) {
42357
+ this.logger.debug?.(
42358
+ `[BaichuanRtspBackchannelServer] RTCP RR write failed client=${session.clientId} session=${session.sessionId} error="${e.message}"`
42359
+ );
42360
+ }
42361
+ };
42362
+ session.rtcpKeepaliveTimer = setInterval(writeOne, RTCP_KEEPALIVE_INTERVAL_MS);
42363
+ if (typeof session.rtcpKeepaliveTimer.unref === "function") {
42364
+ session.rtcpKeepaliveTimer.unref();
42365
+ }
42366
+ this.logger.debug?.(
42367
+ `[BaichuanRtspBackchannelServer] RTCP RR keepalive started client=${session.clientId} session=${session.sessionId} channel=${session.rtcpChannel} ssrc=${session.rtcpSsrc?.toString(16)} interval=${RTCP_KEEPALIVE_INTERVAL_MS}ms`
42368
+ );
42369
+ }
42370
+ stopRtcpKeepalive(session) {
42371
+ if (!session.rtcpKeepaliveTimer) return;
42372
+ clearInterval(session.rtcpKeepaliveTimer);
42373
+ delete session.rtcpKeepaliveTimer;
42374
+ }
42324
42375
  buildSdp() {
42325
42376
  return `v=0\r
42326
42377
  o=- ${Date.now()} ${Date.now()} IN IP4 ${this.listenHost}\r