stormcloud-video-player 0.8.38 → 0.8.39

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.
@@ -1316,10 +1316,56 @@ function buildPlayerTopic(licenseKey, channel) {
1316
1316
  // src/utils/mqttClient.ts
1317
1317
  var import_mqtt = __toESM(require("mqtt"), 1);
1318
1318
  var LOG = "[StormcloudVideoPlayer][MQTT]";
1319
+ var KEEPALIVE_SECONDS = 30;
1320
+ var CONNECT_TIMEOUT_MS = 1e4;
1321
+ var RECONNECT_BASE_MS = 5e3;
1322
+ var RECONNECT_MAX_MS = 6e4;
1323
+ var MAX_RECONNECT_ATTEMPTS = 8;
1324
+ var COOLDOWN_MS = 10 * 6e4;
1319
1325
  var client = null;
1320
1326
  var status = "disconnected";
1321
- function initMQTTClient() {
1322
- if (client || !isMQTTEnabled()) return;
1327
+ var reconnectAttempts = 0;
1328
+ var reconnectTimer = null;
1329
+ var stopped = false;
1330
+ function clearReconnectTimer() {
1331
+ if (reconnectTimer) {
1332
+ clearTimeout(reconnectTimer);
1333
+ reconnectTimer = null;
1334
+ }
1335
+ }
1336
+ function teardownClient() {
1337
+ if (client) {
1338
+ try {
1339
+ client.removeAllListeners();
1340
+ client.end(true);
1341
+ } catch (unused) {}
1342
+ client = null;
1343
+ }
1344
+ }
1345
+ function scheduleReconnect() {
1346
+ if (stopped || !isMQTTEnabled() || reconnectTimer) return;
1347
+ if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
1348
+ console.warn("".concat(LOG, " giving up after ").concat(reconnectAttempts, " attempts; cooling down for ").concat(COOLDOWN_MS / 6e4, "m"));
1349
+ teardownClient();
1350
+ status = "disconnected";
1351
+ reconnectTimer = setTimeout(function() {
1352
+ reconnectTimer = null;
1353
+ reconnectAttempts = 0;
1354
+ openConnection();
1355
+ }, COOLDOWN_MS);
1356
+ return;
1357
+ }
1358
+ var delay = Math.min(RECONNECT_MAX_MS, RECONNECT_BASE_MS * Math.pow(2, reconnectAttempts));
1359
+ var jitter = Math.floor(Math.random() * 1e3);
1360
+ reconnectAttempts += 1;
1361
+ reconnectTimer = setTimeout(function() {
1362
+ reconnectTimer = null;
1363
+ openConnection();
1364
+ }, delay + jitter);
1365
+ }
1366
+ function openConnection() {
1367
+ if (stopped || !isMQTTEnabled()) return;
1368
+ teardownClient();
1323
1369
  var url = buildMQTTBrokerUrl();
1324
1370
  status = "connecting";
1325
1371
  var clientId = "stormcloud-vp-".concat(Math.random().toString(36).slice(2, 9));
@@ -1328,41 +1374,48 @@ function initMQTTClient() {
1328
1374
  clientId: clientId,
1329
1375
  username: mqttConfig.username,
1330
1376
  password: mqttConfig.password,
1331
- keepalive: 60,
1377
+ keepalive: KEEPALIVE_SECONDS,
1332
1378
  clean: true,
1333
- reconnectPeriod: 5e3,
1334
- connectTimeout: 1e4,
1335
- queueQoSZero: false
1379
+ reconnectPeriod: 0,
1380
+ connectTimeout: CONNECT_TIMEOUT_MS,
1381
+ queueQoSZero: false,
1382
+ reschedulePings: true
1336
1383
  });
1337
1384
  } catch (err) {
1338
1385
  status = "error";
1339
1386
  console.warn("".concat(LOG, " connect() threw:"), err);
1387
+ scheduleReconnect();
1340
1388
  return;
1341
1389
  }
1342
1390
  client.on("connect", function() {
1343
1391
  status = "connected";
1392
+ reconnectAttempts = 0;
1393
+ clearReconnectTimer();
1344
1394
  console.info("".concat(LOG, " connected to ").concat(url));
1345
1395
  });
1346
- client.on("reconnect", function() {
1347
- status = "connecting";
1348
- console.info("".concat(LOG, " reconnecting…"));
1349
- });
1350
1396
  client.on("offline", function() {
1351
- status = "disconnected";
1397
+ if (status === "connected") status = "disconnected";
1352
1398
  console.warn("".concat(LOG, " offline"));
1399
+ scheduleReconnect();
1353
1400
  });
1354
1401
  client.on("error", function(err) {
1355
1402
  status = "error";
1356
1403
  console.warn("".concat(LOG, " error:"), err.message);
1404
+ scheduleReconnect();
1357
1405
  });
1358
1406
  client.on("close", function() {
1359
- if (status === "connected") {
1360
- status = "disconnected";
1361
- }
1407
+ if (status === "connected") status = "disconnected";
1408
+ scheduleReconnect();
1362
1409
  });
1363
1410
  }
1411
+ function initMQTTClient() {
1412
+ if (client || !isMQTTEnabled()) return;
1413
+ stopped = false;
1414
+ reconnectAttempts = 0;
1415
+ openConnection();
1416
+ }
1364
1417
  function ensureMQTTClient() {
1365
- if (isMQTTEnabled() && !client) {
1418
+ if (isMQTTEnabled() && !client && !reconnectTimer) {
1366
1419
  initMQTTClient();
1367
1420
  }
1368
1421
  }
@@ -1371,7 +1424,7 @@ function publishMQTT(topic, payload) {
1371
1424
  return false;
1372
1425
  }
1373
1426
  ensureMQTTClient();
1374
- if (!client) {
1427
+ if (!client || !client.connected) {
1375
1428
  return false;
1376
1429
  }
1377
1430
  try {