nodejs-insta-private-api-mqt 1.3.93 → 1.4.1
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.
|
@@ -61,7 +61,7 @@ class MQTToTClient extends mqtts_1.MqttClient {
|
|
|
61
61
|
// Register listeners (errors, disconnect, pingresps, etc.)
|
|
62
62
|
this.registerListeners();
|
|
63
63
|
this.requirePayload = options.requirePayload;
|
|
64
|
-
this._keepaliveMs = (typeof options.keepaliveMs === 'number') ? options.keepaliveMs : (
|
|
64
|
+
this._keepaliveMs = (typeof options.keepaliveMs === 'number') ? options.keepaliveMs : (8 * 60 * 1000);
|
|
65
65
|
this._consecutivePingFailures = 0;
|
|
66
66
|
this._startKeepalive();
|
|
67
67
|
}
|
|
@@ -69,7 +69,7 @@ class MQTToTClient extends mqtts_1.MqttClient {
|
|
|
69
69
|
try {
|
|
70
70
|
if (this._keepaliveTimer)
|
|
71
71
|
clearInterval(this._keepaliveTimer);
|
|
72
|
-
const jitter = Math.floor(Math.random() *
|
|
72
|
+
const jitter = Math.floor(Math.random() * 30000);
|
|
73
73
|
this._keepaliveTimer = setInterval(() => {
|
|
74
74
|
try {
|
|
75
75
|
if (typeof this.ping === 'function') {
|
|
@@ -147,7 +147,7 @@ class MQTToTClient extends mqtts_1.MqttClient {
|
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
149
|
let delay = 3000 + Math.floor(Math.random() * 2000);
|
|
150
|
-
const maxAttempts =
|
|
150
|
+
const maxAttempts = 12;
|
|
151
151
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
152
152
|
try {
|
|
153
153
|
this.mqttotDebug(`Reconnect attempt #${attempt + 1} (delay ${delay}ms)`);
|
|
@@ -30,7 +30,7 @@ class ErrorHandler {
|
|
|
30
30
|
constructor(client) {
|
|
31
31
|
this.errorDebug = (0, shared_1.debugChannel)('realtime', 'errors');
|
|
32
32
|
this.errorCount = 0;
|
|
33
|
-
this.maxRetries =
|
|
33
|
+
this.maxRetries = 15;
|
|
34
34
|
this.client = client;
|
|
35
35
|
this.errorHistory = [];
|
|
36
36
|
this.rateLimitUntil = 0;
|
|
@@ -1036,8 +1036,48 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
1036
1036
|
// actually connect the mqtt client (this will emit connect when done)
|
|
1037
1037
|
await this._mqtt.connect();
|
|
1038
1038
|
// Commands uses mqtt client; Commands.updateSubscriptions has been set to use qos 0.
|
|
1039
|
-
|
|
1040
|
-
|
|
1039
|
+
// Commands uses mqtt client; wrap commands to ensure online + serialize calls (prevents "idle-dead" send failures)
|
|
1040
|
+
|
|
1041
|
+
this._rawCommands = new commands_1.Commands(this._mqtt);
|
|
1042
|
+
|
|
1043
|
+
// Simple promise-chain queue to avoid concurrent publishes racing during reconnects
|
|
1044
|
+
|
|
1045
|
+
this._cmdQueue = this._cmdQueue || Promise.resolve();
|
|
1046
|
+
|
|
1047
|
+
const runQueued = (fn) => {
|
|
1048
|
+
|
|
1049
|
+
const task = async () => {
|
|
1050
|
+
|
|
1051
|
+
await this.ensureOnline(); // ping/reconnect if needed
|
|
1052
|
+
|
|
1053
|
+
return await fn();
|
|
1054
|
+
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
// keep the queue alive even if a task fails
|
|
1058
|
+
|
|
1059
|
+
this._cmdQueue = this._cmdQueue.then(task, task);
|
|
1060
|
+
|
|
1061
|
+
return this._cmdQueue;
|
|
1062
|
+
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
// Proxy: every command method becomes queued + guarded
|
|
1066
|
+
|
|
1067
|
+
this.commands = new Proxy(this._rawCommands, {
|
|
1068
|
+
|
|
1069
|
+
get: (target, prop) => {
|
|
1070
|
+
|
|
1071
|
+
const value = target[prop];
|
|
1072
|
+
|
|
1073
|
+
if (typeof value !== 'function') return value;
|
|
1074
|
+
|
|
1075
|
+
return (...args) => runQueued(() => value.apply(target, args));
|
|
1076
|
+
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
});
|
|
1080
|
+
// Notify higher-level code that we are connected
|
|
1041
1081
|
this._mqttConnected = true;
|
|
1042
1082
|
this._connectInProgress = false;
|
|
1043
1083
|
this.emit('connected');
|
|
@@ -2165,5 +2205,80 @@ class RealtimeClient extends eventemitter3_1.EventEmitter {
|
|
|
2165
2205
|
this.realtimeDebug('[ACTIVE_QUERY] could not start keepalive timer:', e?.message || e);
|
|
2166
2206
|
}
|
|
2167
2207
|
}
|
|
2208
|
+
/**
|
|
2209
|
+
* ensureOnline()
|
|
2210
|
+
* - fixes the classic "idle -> socket half-dead -> sends fail" issue
|
|
2211
|
+
* - pings the broker; if ping fails/timeouts, triggers a safe reconnect and waits until connected
|
|
2212
|
+
*/
|
|
2213
|
+
async ensureOnline(options = {}) {
|
|
2214
|
+
const timeoutMs = typeof options.timeoutMs === 'number' ? options.timeoutMs : 15000;
|
|
2215
|
+
const pingTimeoutMs = typeof options.pingTimeoutMs === 'number' ? options.pingTimeoutMs : 7000;
|
|
2216
|
+
if (this.safeDisconnect) {
|
|
2217
|
+
throw new Error('RealtimeClient is in safeDisconnect state');
|
|
2218
|
+
}
|
|
2219
|
+
// If a connect/reconnect is already happening, just wait for it
|
|
2220
|
+
if (this._connectInProgress || this._reconnectInProgress) {
|
|
2221
|
+
await this._waitForConnected(timeoutMs);
|
|
2222
|
+
return true;
|
|
2223
|
+
}
|
|
2224
|
+
// If we are not connected, reconnect and wait
|
|
2225
|
+
if (!this._mqtt || !this._mqttConnected) {
|
|
2226
|
+
try {
|
|
2227
|
+
await this._attemptReconnectSafely();
|
|
2228
|
+
} catch (e) { /* ignore */ }
|
|
2229
|
+
await this._waitForConnected(timeoutMs);
|
|
2230
|
+
return true;
|
|
2231
|
+
}
|
|
2232
|
+
// If we are connected, do a lightweight ping to detect half-dead sockets
|
|
2233
|
+
if (this._mqtt && typeof this._mqtt.ping === 'function') {
|
|
2234
|
+
try {
|
|
2235
|
+
await Promise.race([
|
|
2236
|
+
this._mqtt.ping(),
|
|
2237
|
+
this._delay(pingTimeoutMs).then(() => { throw new Error('mqtt.ping timeout'); })
|
|
2238
|
+
]);
|
|
2239
|
+
this._lastMessageAt = Date.now();
|
|
2240
|
+
this._lastServerTrafficAt = Date.now();
|
|
2241
|
+
return true;
|
|
2242
|
+
} catch (e) {
|
|
2243
|
+
// Ping failed -> force reconnect
|
|
2244
|
+
this.realtimeDebug('[ensureOnline] ping failed -> reconnect', e?.message || e);
|
|
2245
|
+
this._mqttConnected = false;
|
|
2246
|
+
try { await this._attemptReconnectSafely(e); } catch (re) { /* ignore */ }
|
|
2247
|
+
await this._waitForConnected(timeoutMs);
|
|
2248
|
+
return true;
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
return true;
|
|
2252
|
+
}
|
|
2253
|
+
_delay(ms) {
|
|
2254
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2255
|
+
}
|
|
2256
|
+
_waitForConnected(timeoutMs) {
|
|
2257
|
+
return new Promise((resolve, reject) => {
|
|
2258
|
+
if (this._mqttConnected) return resolve(true);
|
|
2259
|
+
let done = false;
|
|
2260
|
+
const finishOk = () => {
|
|
2261
|
+
if (done) return;
|
|
2262
|
+
done = true;
|
|
2263
|
+
cleanup();
|
|
2264
|
+
resolve(true);
|
|
2265
|
+
};
|
|
2266
|
+
const finishErr = (err) => {
|
|
2267
|
+
if (done) return;
|
|
2268
|
+
done = true;
|
|
2269
|
+
cleanup();
|
|
2270
|
+
reject(err);
|
|
2271
|
+
};
|
|
2272
|
+
const timer = setTimeout(() => finishErr(new Error('Timed out waiting for MQTT connection')), timeoutMs);
|
|
2273
|
+
const cleanup = () => {
|
|
2274
|
+
try { clearTimeout(timer); } catch (_) { }
|
|
2275
|
+
try { this.off('connected', finishOk); } catch (_) { }
|
|
2276
|
+
try { this.off('mqtt_connected', finishOk); } catch (_) { }
|
|
2277
|
+
};
|
|
2278
|
+
try { this.on('connected', finishOk); } catch (_) { }
|
|
2279
|
+
try { this.on('mqtt_connected', finishOk); } catch (_) { }
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2168
2283
|
}
|
|
2169
2284
|
exports.RealtimeClient = RealtimeClient;
|