livedesk 0.1.248 → 0.1.250
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 +8 -0
- package/bin/livedesk.js +66 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,14 @@ This starts the LiveDesk Hub, opens the local screen wall, and accepts clients.
|
|
|
13
13
|
The Hub UI/API listens on `127.0.0.1` by default while the client endpoint
|
|
14
14
|
continues to listen on the LAN.
|
|
15
15
|
|
|
16
|
+
On startup, the launcher finds stale processes whose command line identifies
|
|
17
|
+
them as a LiveDesk Hub, even if the old Hub is still starting and has not
|
|
18
|
+
finished binding its ports. It also checks the Hub ports (`5179` and `5197`),
|
|
19
|
+
waits for the old process and both ports to be released, and then starts the
|
|
20
|
+
new Hub. An unrelated process is preserved and reported instead of being
|
|
21
|
+
terminated; use `--port`, `--remote-port`, or stop that process manually. Pass
|
|
22
|
+
`--no-clean` to disable the startup cleanup explicitly.
|
|
23
|
+
|
|
16
24
|
## Client
|
|
17
25
|
|
|
18
26
|
```powershell
|
package/bin/livedesk.js
CHANGED
|
@@ -222,21 +222,77 @@ async function stopProcessesOnPorts(ports) {
|
|
|
222
222
|
const script = [
|
|
223
223
|
'$ErrorActionPreference = "SilentlyContinue";',
|
|
224
224
|
`$ports = @(${uniquePorts.join(',')});`,
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
`$currentNodePid = ${process.pid};`,
|
|
226
|
+
" $hubProcessPattern = '(?i)(?:livedesk|@livedesk).*hub[\\\\/].*server\\.js';",
|
|
227
|
+
'function Get-ListenConnections($port) {',
|
|
228
|
+
' $connections = @(Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue);',
|
|
229
|
+
' if ($connections.Count -gt 0) { return $connections }',
|
|
230
|
+
' $pattern = "^\\s*TCP\\s+\\S+:" + $port + "\\s+\\S+\\s+LISTENING\\s+(\\d+)\\s*$";',
|
|
231
|
+
' foreach ($line in @(netstat -ano -p tcp)) {',
|
|
232
|
+
' $match = [regex]::Match([string]$line, $pattern);',
|
|
233
|
+
' if ($match.Success) {',
|
|
234
|
+
' [pscustomobject]@{ LocalPort = [int]$port; OwningProcess = [int]$match.Groups[1].Value }',
|
|
235
|
+
' }',
|
|
236
|
+
' }',
|
|
237
|
+
'}',
|
|
238
|
+
'$records = foreach ($port in $ports) {',
|
|
239
|
+
' $connections = @(Get-ListenConnections $port | Where-Object { $_.OwningProcess -and $_.OwningProcess -ne $currentNodePid });',
|
|
240
|
+
' foreach ($connection in $connections) {',
|
|
241
|
+
' $owner = [int]$connection.OwningProcess;',
|
|
242
|
+
' $proc = Get-CimInstance Win32_Process -Filter "ProcessId = $owner" -ErrorAction SilentlyContinue;',
|
|
243
|
+
' $processName = if ($proc) { [string]$proc.Name } else { "" };',
|
|
244
|
+
' $commandLine = if ($proc) { [string]$proc.CommandLine } else { "" };',
|
|
245
|
+
' $knownLiveDesk = $commandLine -match "(?i)(?:livedesk|@livedesk).*hub[\\\\/].*server\\.js";',
|
|
246
|
+
' [pscustomobject]@{ Port = [int]$port; Pid = $owner; ProcessName = $processName; CommandLine = $commandLine; KnownLiveDesk = [bool]$knownLiveDesk; Action = "preserved"; PortAvailable = $false; ProcessGone = $false }',
|
|
247
|
+
' }',
|
|
227
248
|
'}',
|
|
228
|
-
'$
|
|
229
|
-
'
|
|
230
|
-
'
|
|
231
|
-
' if ($proc) {',
|
|
232
|
-
'
|
|
233
|
-
' Stop-Process -Id $owner -Force -ErrorAction SilentlyContinue;',
|
|
249
|
+
'$records = @($records | Sort-Object Port,Pid -Unique);',
|
|
250
|
+
'$hubProcesses = @(Get-CimInstance Win32_Process -ErrorAction SilentlyContinue | Where-Object { $_.ProcessId -and $_.ProcessId -ne $currentNodePid -and ([string]$_.Name) -ieq "node.exe" -and ([string]$_.CommandLine) -match $hubProcessPattern });',
|
|
251
|
+
'foreach ($proc in $hubProcesses) {',
|
|
252
|
+
' if (-not (@($records | Where-Object { $_.Pid -eq [int]$proc.ProcessId }).Count)) {',
|
|
253
|
+
' $records += [pscustomobject]@{ Port = 0; Pid = [int]$proc.ProcessId; ProcessName = [string]$proc.Name; CommandLine = [string]$proc.CommandLine; KnownLiveDesk = $true; Action = "preserved"; PortAvailable = $false; ProcessGone = $false }',
|
|
234
254
|
' }',
|
|
235
|
-
'}'
|
|
255
|
+
'}',
|
|
256
|
+
'foreach ($record in @($records | Where-Object { $_.KnownLiveDesk })) {',
|
|
257
|
+
' Stop-Process -Id $record.Pid -Force -ErrorAction SilentlyContinue;',
|
|
258
|
+
' $record.Action = "stopped";',
|
|
259
|
+
'}',
|
|
260
|
+
'$deadline = (Get-Date).ToUniversalTime().AddMilliseconds(3000);',
|
|
261
|
+
'do {',
|
|
262
|
+
' $busyPorts = @($ports | ForEach-Object { Get-ListenConnections $_ });',
|
|
263
|
+
' $busyHubPids = @($records | Where-Object { $_.KnownLiveDesk } | ForEach-Object { Get-Process -Id $_.Pid -ErrorAction SilentlyContinue });',
|
|
264
|
+
' if (($busyPorts.Count -eq 0 -and $busyHubPids.Count -eq 0) -or (Get-Date).ToUniversalTime() -ge $deadline) { break }',
|
|
265
|
+
' Start-Sleep -Milliseconds 100;',
|
|
266
|
+
'} while ($true);',
|
|
267
|
+
'$busyPortNumbers = @($busyPorts | Select-Object -ExpandProperty LocalPort -Unique);',
|
|
268
|
+
'foreach ($record in $records) {',
|
|
269
|
+
' $record.PortAvailable = $busyPortNumbers -notcontains $record.Port;',
|
|
270
|
+
' $record.ProcessGone = -not (Get-Process -Id $record.Pid -ErrorAction SilentlyContinue);',
|
|
271
|
+
'}',
|
|
272
|
+
'$records | ConvertTo-Json -Compress'
|
|
236
273
|
].join(' ');
|
|
237
274
|
const result = await runQuiet('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', script]);
|
|
275
|
+
if (!result.ok && !result.stdout) {
|
|
276
|
+
throw new Error(`Could not inspect existing LiveDesk Hub ports: ${result.stderr || result.error?.message || 'PowerShell failed'}`);
|
|
277
|
+
}
|
|
278
|
+
let records = [];
|
|
238
279
|
if (result.stdout) {
|
|
239
|
-
|
|
280
|
+
try {
|
|
281
|
+
const parsed = JSON.parse(result.stdout);
|
|
282
|
+
records = Array.isArray(parsed) ? parsed : [parsed];
|
|
283
|
+
} catch {
|
|
284
|
+
throw new Error(`Could not parse existing LiveDesk Hub port state: ${result.stdout}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
const stopped = records.filter(record => record?.Action === 'stopped');
|
|
288
|
+
if (stopped.length > 0) {
|
|
289
|
+
const summary = stopped.map(record => `${record.Pid}:${record.ProcessName || 'node'}${record.Port ? `@${record.Port}` : ''}`).join(', ');
|
|
290
|
+
console.log(`Restarting LiveDesk Hub. Stopped stale LiveDesk owner(s): ${summary}`);
|
|
291
|
+
}
|
|
292
|
+
const blocked = records.filter(record => record?.PortAvailable !== true || (record?.Port === 0 && record?.ProcessGone !== true));
|
|
293
|
+
if (blocked.length > 0) {
|
|
294
|
+
const summary = blocked.map(record => `${record.Pid}:${record.ProcessName || 'unknown'}@${record.Port}[port-free=${record.PortAvailable === true},process-gone=${record.ProcessGone === true}]`).join(', ');
|
|
295
|
+
throw new Error(`LiveDesk Hub startup cleanup could not release port/process owner(s): ${summary}. If this is an unrelated process, use --port/--remote-port or stop it manually.`);
|
|
240
296
|
}
|
|
241
297
|
return;
|
|
242
298
|
}
|