n8n-nodes-chat2crm 0.1.20 → 0.1.21

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.
@@ -260,10 +260,33 @@ class Chat2CrmTrigger {
260
260
  // Запускаем один последовательный polling loop (без setInterval), чтобы не было наложения вызовов
261
261
  let pollingPromise = null;
262
262
  const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
263
+ const KEEPALIVE_INTERVAL_MS = 30_000;
264
+ let lastKeepaliveAt = Date.now();
265
+ const keepalive = async () => {
266
+ const now = Date.now();
267
+ if (now - lastKeepaliveAt < KEEPALIVE_INTERVAL_MS)
268
+ return;
269
+ lastKeepaliveAt = now;
270
+ for (const [db, redis] of redisConnections.entries()) {
271
+ if (isClosing)
272
+ return;
273
+ try {
274
+ await redis.ping();
275
+ if (isDebug) {
276
+ console.log(`[Chat2Crm Trigger] Keepalive PING OK (DB ${db})`);
277
+ }
278
+ }
279
+ catch (error) {
280
+ // Не роняем триггер из-за keepalive — это best-effort. Ошибка даст сигнал, что SSH/Redis начинает умирать.
281
+ console.error(`[Chat2Crm Trigger] Keepalive PING failed (DB ${db}):`, error?.message ?? error);
282
+ }
283
+ }
284
+ };
263
285
  const runPollingLoop = async () => {
264
286
  try {
265
287
  while (!isClosing) {
266
288
  await readMessages();
289
+ await keepalive();
267
290
  // Если block=0, добавляем небольшой интервал чтобы не прожигать CPU
268
291
  if (!isClosing) {
269
292
  await sleep(pollInterval);
@@ -117,6 +117,13 @@ async function createRedisConnection(credentials, db = 0) {
117
117
  console.log(`[Redis Connection] Creating tunnel to Redis at ${remoteRedisHost}:${remoteRedisPort} on remote server`);
118
118
  // Создаем локальный TCP сервер для проксирования через SSH туннель
119
119
  const localServer = net.createServer((localSocket) => {
120
+ // TCP keepalive помогает держать соединение живым при длительном простое (важно для SSH/прокси/фаерволов)
121
+ try {
122
+ localSocket.setKeepAlive(true, 60_000); // 60 секунд
123
+ }
124
+ catch (e) {
125
+ // best-effort
126
+ }
120
127
  // Создаем SSH туннель для каждого соединения
121
128
  sshClient.forwardOut('127.0.0.1', 0, remoteRedisHost, remoteRedisPort, (err, stream) => {
122
129
  if (err) {
@@ -177,6 +184,8 @@ async function createRedisConnection(credentials, db = 0) {
177
184
  enableReadyCheck: true,
178
185
  maxRetriesPerRequest: 3,
179
186
  connectTimeout: 10000,
187
+ // TCP keepalive для предотвращения "тихих" разрывов соединения при простое (особенно через SSH)
188
+ keepAlive: 30_000,
180
189
  retryStrategy: (times) => {
181
190
  const delay = Math.min(times * 50, 2000);
182
191
  return delay;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-chat2crm",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "n8n node for Chat2Crm Redis integration",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",