livedesk 0.1.251 → 0.1.252
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/README.md +6 -6
- package/bin/livedesk.js +4 -10
- package/hub/src/remote-hub.js +12 -54
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,12 +16,12 @@ continues to listen on the LAN.
|
|
|
16
16
|
On startup, the launcher finds stale processes whose command line identifies
|
|
17
17
|
them as a LiveDesk Hub, even if the old Hub is still starting and has not
|
|
18
18
|
finished binding its ports. It also checks the Hub ports (`5179` and `5197`),
|
|
19
|
-
waits for stale LiveDesk processes to exit, and then starts the new Hub.
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
waits for stale LiveDesk processes to exit, and then starts the new Hub. The
|
|
20
|
+
client endpoint remains fixed at TCP `5197` by default so firewall rules,
|
|
21
|
+
router forwarding, and direct clients keep a stable contract. An unrelated
|
|
22
|
+
process is preserved and reported instead of being terminated; stop it or use
|
|
23
|
+
an explicit `--remote-port` value. Pass `--no-clean` to disable the startup
|
|
24
|
+
cleanup explicitly.
|
|
25
25
|
|
|
26
26
|
## Client
|
|
27
27
|
|
package/bin/livedesk.js
CHANGED
|
@@ -37,8 +37,7 @@ Hub options:
|
|
|
37
37
|
--host <host> Hub HTTP host. Default: 127.0.0.1
|
|
38
38
|
--port <port> Hub HTTP port. Default: 5179
|
|
39
39
|
--remote-port <port>
|
|
40
|
-
|
|
41
|
-
LiveDesk retries on a nearby port automatically.
|
|
40
|
+
Client connection port. Default: 5197.
|
|
42
41
|
--no-clean Do not stop existing processes on the Hub ports.
|
|
43
42
|
|
|
44
43
|
Common:
|
|
@@ -213,7 +212,7 @@ function runQuiet(command, args) {
|
|
|
213
212
|
});
|
|
214
213
|
}
|
|
215
214
|
|
|
216
|
-
async function stopProcessesOnPorts(ports
|
|
215
|
+
async function stopProcessesOnPorts(ports) {
|
|
217
216
|
const uniquePorts = [...new Set(ports.map(port => normalizePort(port, 0)).filter(Boolean))];
|
|
218
217
|
if (uniquePorts.length === 0) {
|
|
219
218
|
return;
|
|
@@ -293,11 +292,7 @@ async function stopProcessesOnPorts(ports, { allowBusyPorts = false } = {}) {
|
|
|
293
292
|
const blocked = records.filter(record => record?.PortAvailable !== true || (record?.Port === 0 && record?.ProcessGone !== true));
|
|
294
293
|
if (blocked.length > 0) {
|
|
295
294
|
const summary = blocked.map(record => `${record.Pid}:${record.ProcessName || 'unknown'}@${record.Port}[port-free=${record.PortAvailable === true},process-gone=${record.ProcessGone === true}]`).join(', ');
|
|
296
|
-
|
|
297
|
-
if (!allowBusyPorts) {
|
|
298
|
-
throw new Error(`${message}. If this is an unrelated process, use --port or stop it manually.`);
|
|
299
|
-
}
|
|
300
|
-
console.warn(`${message}. The client endpoint will retry on another port automatically.`);
|
|
295
|
+
throw new Error(`LiveDesk Hub startup cleanup could not release port/process owner(s): ${summary}. LiveDesk keeps the configured port fixed; stop that process or choose an explicit --port/--remote-port value.`);
|
|
301
296
|
}
|
|
302
297
|
return;
|
|
303
298
|
}
|
|
@@ -355,8 +350,7 @@ async function runManager(args) {
|
|
|
355
350
|
|| getStablePairToken();
|
|
356
351
|
|
|
357
352
|
if (options.cleanPortsOnStart) {
|
|
358
|
-
await stopProcessesOnPorts([httpPort]);
|
|
359
|
-
await stopProcessesOnPorts([remotePort], { allowBusyPorts: true });
|
|
353
|
+
await stopProcessesOnPorts([httpPort, remotePort]);
|
|
360
354
|
}
|
|
361
355
|
|
|
362
356
|
const internalHubEntry = resolve(packageRoot, 'hub', 'src', 'server.js');
|
package/hub/src/remote-hub.js
CHANGED
|
@@ -4,8 +4,6 @@ import crypto from 'crypto';
|
|
|
4
4
|
|
|
5
5
|
const DEFAULT_REMOTE_HUB_PORT = 5197;
|
|
6
6
|
const DEFAULT_REMOTE_HUB_HOST = '0.0.0.0';
|
|
7
|
-
const DEFAULT_REMOTE_HUB_PORT_FALLBACK_ATTEMPTS = 32;
|
|
8
|
-
const REMOTE_HUB_AUTH_CALLBACK_PORT = 5198;
|
|
9
7
|
const DEFAULT_HEARTBEAT_MS = 5000;
|
|
10
8
|
const DEFAULT_AGENT_TASK_TIMEOUT_MS = 120000;
|
|
11
9
|
const MAX_LINE_CHARS = 4 * 1024 * 1024;
|
|
@@ -1419,14 +1417,6 @@ export function createRemoteHub(options = {}) {
|
|
|
1419
1417
|
&& !isDisabledValue(env.REMOTE_HUB_DISABLED);
|
|
1420
1418
|
const host = safeString(env.REMOTE_HUB_HOST || DEFAULT_REMOTE_HUB_HOST, 128);
|
|
1421
1419
|
const requestedPort = normalizePort(env.REMOTE_HUB_PORT || DEFAULT_REMOTE_HUB_PORT);
|
|
1422
|
-
const remotePortFallbackEnabled = isEnabledValue(env.REMOTE_HUB_PORT_FALLBACK, true)
|
|
1423
|
-
&& !isDisabledValue(env.REMOTE_HUB_PORT_FALLBACK_DISABLED);
|
|
1424
|
-
const remotePortFallbackStrict = isEnabledValue(env.REMOTE_HUB_PORT_FALLBACK_STRICT, false);
|
|
1425
|
-
const remotePortFallbackAttempts = clampNumber(
|
|
1426
|
-
env.REMOTE_HUB_PORT_FALLBACK_ATTEMPTS,
|
|
1427
|
-
1,
|
|
1428
|
-
128,
|
|
1429
|
-
DEFAULT_REMOTE_HUB_PORT_FALLBACK_ATTEMPTS);
|
|
1430
1420
|
const heartbeatMs = clampNumber(env.REMOTE_HUB_HEARTBEAT_MS, 1000, 60000, DEFAULT_HEARTBEAT_MS);
|
|
1431
1421
|
const taskTimeoutMs = clampNumber(
|
|
1432
1422
|
options.taskTimeoutMs ?? env.REMOTE_HUB_TASK_TIMEOUT_MS,
|
|
@@ -4381,17 +4371,6 @@ export function createRemoteHub(options = {}) {
|
|
|
4381
4371
|
});
|
|
4382
4372
|
}
|
|
4383
4373
|
|
|
4384
|
-
function getNextFallbackPort(currentPort, attemptedPorts) {
|
|
4385
|
-
for (let offset = 1; offset <= 65535; offset += 1) {
|
|
4386
|
-
const candidate = (currentPort + offset) % 65536;
|
|
4387
|
-
if (candidate < 1 || candidate === REMOTE_HUB_AUTH_CALLBACK_PORT || attemptedPorts.has(candidate)) {
|
|
4388
|
-
continue;
|
|
4389
|
-
}
|
|
4390
|
-
return candidate;
|
|
4391
|
-
}
|
|
4392
|
-
return 0;
|
|
4393
|
-
}
|
|
4394
|
-
|
|
4395
4374
|
function listenOnPort(port) {
|
|
4396
4375
|
return new Promise((resolve, reject) => {
|
|
4397
4376
|
const candidateServer = net.createServer(handleSocket);
|
|
@@ -4422,40 +4401,19 @@ export function createRemoteHub(options = {}) {
|
|
|
4422
4401
|
return getStatus({ includeSecrets: false });
|
|
4423
4402
|
}
|
|
4424
4403
|
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4436
|
-
if (candidatePort !== requestedPort) {
|
|
4437
|
-
logWarn(
|
|
4438
|
-
'remote',
|
|
4439
|
-
`Client port ${requestedPort} is already in use; LiveDesk Hub is using ${candidatePort}.`);
|
|
4440
|
-
}
|
|
4441
|
-
lastBindError = null;
|
|
4442
|
-
break;
|
|
4443
|
-
} catch (error) {
|
|
4444
|
-
lastBindError = error;
|
|
4445
|
-
if (error?.code !== 'EADDRINUSE' || !fallbackAllowed) {
|
|
4446
|
-
throw error;
|
|
4447
|
-
}
|
|
4448
|
-
|
|
4449
|
-
const nextPort = getNextFallbackPort(candidatePort, attemptedPorts);
|
|
4450
|
-
if (!nextPort) {
|
|
4451
|
-
break;
|
|
4452
|
-
}
|
|
4453
|
-
candidatePort = nextPort;
|
|
4404
|
+
try {
|
|
4405
|
+
await listenOnPort(requestedPort);
|
|
4406
|
+
} catch (error) {
|
|
4407
|
+
if (error?.code === 'EADDRINUSE') {
|
|
4408
|
+
const conflict = new Error(
|
|
4409
|
+
`LiveDesk Hub requires client endpoint TCP ${requestedPort}, but that port is already in use. Close the owning process or start Hub with an explicit --remote-port value.`);
|
|
4410
|
+
conflict.code = 'EADDRINUSE';
|
|
4411
|
+
conflict.port = requestedPort;
|
|
4412
|
+
conflict.cause = error;
|
|
4413
|
+
lastError = conflict.message;
|
|
4414
|
+
throw conflict;
|
|
4454
4415
|
}
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
if (lastBindError) {
|
|
4458
|
-
throw lastBindError;
|
|
4416
|
+
throw error;
|
|
4459
4417
|
}
|
|
4460
4418
|
|
|
4461
4419
|
return getStatus({ includeSecrets: false });
|