hopefully fix
This commit is contained in:
@@ -547,7 +547,7 @@ func runSession(ctx context.Context, cancel context.CancelFunc, conn *websocket.
|
|||||||
sendCtx, sendCancel := context.WithTimeout(context.Background(), 2*time.Second)
|
sendCtx, sendCancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||||
defer sendCancel()
|
defer sendCancel()
|
||||||
_ = wire.WriteMsg(sendCtx, conn, di)
|
_ = wire.WriteMsg(sendCtx, conn, di)
|
||||||
conn.Close(websocket.StatusNormalClosure, "bye")
|
conn.CloseNow()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
identity := config.DeriveIdentity()
|
identity := config.DeriveIdentity()
|
||||||
@@ -747,8 +747,8 @@ func runSession(ctx context.Context, cancel context.CancelFunc, conn *websocket.
|
|||||||
last := env.LastPong()
|
last := env.LastPong()
|
||||||
if !last.IsZero() && time.Since(last) > grace {
|
if !last.IsZero() && time.Since(last) > grace {
|
||||||
log.Printf("ping: no pong for %s, forcing reconnect", time.Since(last))
|
log.Printf("ping: no pong for %s, forcing reconnect", time.Since(last))
|
||||||
conn.Close(websocket.StatusGoingAway, "pong timeout")
|
|
||||||
cancel()
|
cancel()
|
||||||
|
conn.CloseNow()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -857,6 +857,20 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
setStreamState("connecting", "Connecting");
|
setStreamState("connecting", "Connecting");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (msg.status === "starting") {
|
||||||
|
clearOfflineTimer();
|
||||||
|
if (desiredStreaming && streamState !== "streaming") {
|
||||||
|
setStreamState("starting", "Starting stream");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (msg.status === "stopped") {
|
||||||
|
clearOfflineTimer();
|
||||||
|
desiredStreaming = false;
|
||||||
|
lastFrameAt = 0;
|
||||||
|
setStreamState("idle", "Stopped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (msg.status === "online") {
|
if (msg.status === "online") {
|
||||||
clearOfflineTimer();
|
clearOfflineTimer();
|
||||||
if (elevationPending) {
|
if (elevationPending) {
|
||||||
@@ -1348,10 +1362,12 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
stopBtn.addEventListener("click", function () {
|
stopBtn.addEventListener("click", function () {
|
||||||
if (isRecording()) stopRecording();
|
if (isRecording()) stopRecording();
|
||||||
desiredStreaming = false;
|
desiredStreaming = false;
|
||||||
|
lastFrameAt = 0;
|
||||||
setStreamState("stopping", "Stopping stream");
|
setStreamState("stopping", "Stopping stream");
|
||||||
sendCmd("desktop_stop", {});
|
sendCmd("desktop_stop", {});
|
||||||
disconnectAudio();
|
disconnectAudio();
|
||||||
stopAllWebrtc();
|
stopAllWebrtc();
|
||||||
|
setStreamState("idle", "Stopped");
|
||||||
});
|
});
|
||||||
if (recordBtn) {
|
if (recordBtn) {
|
||||||
recordBtn.addEventListener("click", function () {
|
recordBtn.addEventListener("click", function () {
|
||||||
|
|||||||
@@ -566,7 +566,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
hasRenderedFrame = true;
|
hasRenderedFrame = true;
|
||||||
bitmap.close();
|
bitmap.close();
|
||||||
updateViewerFps();
|
updateViewerFps();
|
||||||
setStreamState("streaming", "Streaming");
|
if (desiredStreaming) setStreamState("streaming", "Streaming");
|
||||||
} finally {
|
} finally {
|
||||||
drawPending = false;
|
drawPending = false;
|
||||||
}
|
}
|
||||||
@@ -600,7 +600,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
h264TimestampUs += 66_666;
|
h264TimestampUs += 66_666;
|
||||||
videoDecoder.decode(chunk);
|
videoDecoder.decode(chunk);
|
||||||
updateViewerFps();
|
updateViewerFps();
|
||||||
setStreamState("streaming", "Streaming");
|
if (desiredStreaming) setStreamState("streaming", "Streaming");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("webcam h264 decode failed", err, "payloadBytes=", payload.length);
|
console.warn("webcam h264 decode failed", err, "payloadBytes=", payload.length);
|
||||||
}
|
}
|
||||||
@@ -698,6 +698,13 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
if (msg.status === "offline") {
|
if (msg.status === "offline") {
|
||||||
desiredStreaming = false;
|
desiredStreaming = false;
|
||||||
setStreamState("offline", msg.reason || "Client offline");
|
setStreamState("offline", msg.reason || "Client offline");
|
||||||
|
} else if (msg.status === "starting") {
|
||||||
|
if (desiredStreaming && streamState !== "streaming") {
|
||||||
|
setStreamState("starting", "Starting");
|
||||||
|
}
|
||||||
|
} else if (msg.status === "stopped") {
|
||||||
|
desiredStreaming = false;
|
||||||
|
setStreamState("idle", "Stopped");
|
||||||
} else if (msg.status === "connecting") {
|
} else if (msg.status === "connecting") {
|
||||||
setStreamState("idle", "Ready");
|
setStreamState("idle", "Ready");
|
||||||
} else if (msg.status === "online") {
|
} else if (msg.status === "online") {
|
||||||
@@ -790,12 +797,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
send("webcam_stop");
|
send("webcam_stop");
|
||||||
stopAllWebrtc();
|
stopAllWebrtc();
|
||||||
disconnectAudio();
|
disconnectAudio();
|
||||||
setStreamState("stopping", "Stopping");
|
setStreamState("idle", "Stopped");
|
||||||
setTimeout(() => {
|
|
||||||
if (streamState === "stopping") {
|
|
||||||
setStreamState("idle", "Stopped");
|
|
||||||
}
|
|
||||||
}, 300);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function stopOnExit() {
|
function stopOnExit() {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ describe("pruneStaleClients", () => {
|
|||||||
expect(deleted).toEqual([]);
|
expect(deleted).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("closes and marks offline stale role=client entries without deleting", () => {
|
test("closes, marks offline, and deletes stale role=client entries", () => {
|
||||||
const clients = new Map<string, ClientInfo>();
|
const clients = new Map<string, ClientInfo>();
|
||||||
const staleClient = makeClient("stale-c", Date.now() - 120_000, "client");
|
const staleClient = makeClient("stale-c", Date.now() - 120_000, "client");
|
||||||
clients.set("stale-c", staleClient);
|
clients.set("stale-c", staleClient);
|
||||||
@@ -53,7 +53,7 @@ describe("pruneStaleClients", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
expect(offlined).toContain("stale-c");
|
expect(offlined).toContain("stale-c");
|
||||||
expect(deleted).not.toContain("stale-c");
|
expect(deleted).toContain("stale-c");
|
||||||
expect((staleClient.ws as any)._calls[0]).toStartWith("close:");
|
expect((staleClient.ws as any)._calls[0]).toStartWith("close:");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export function pruneStaleClients(params: PruneStaleClientsParams): void {
|
|||||||
if (info.role === "client") {
|
if (info.role === "client") {
|
||||||
info.ws.close(4000, "stale");
|
info.ws.close(4000, "stale");
|
||||||
params.setOnlineState(id, false);
|
params.setOnlineState(id, false);
|
||||||
|
params.deleteClient(id);
|
||||||
processed += 1;
|
processed += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -390,6 +390,7 @@ export function handleRemoteDesktopViewerMessage(ws: ServerWebSocket<SocketData>
|
|||||||
whepPath: `/api/webrtc/${streamPath}/whep`,
|
whepPath: `/api/webrtc/${streamPath}/whep`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
safeSendViewer(ws, { type: "status", status: "starting" });
|
||||||
sendDesktopCommand(target, "desktop_set_fps", { fps: clampDesktopFps(state.maxFps) });
|
sendDesktopCommand(target, "desktop_set_fps", { fps: clampDesktopFps(state.maxFps) });
|
||||||
sendDesktopCommand(target, "desktop_start", {});
|
sendDesktopCommand(target, "desktop_start", {});
|
||||||
state.isStreaming = true;
|
state.isStreaming = true;
|
||||||
@@ -403,6 +404,7 @@ export function handleRemoteDesktopViewerMessage(ws: ServerWebSocket<SocketData>
|
|||||||
logger.info(`[rd-debug] desktop_start reasserting stale stream client=${clientId} lastFrameAgeMs=${Number.isFinite(lastFrameAgeMs) ? lastFrameAgeMs : -1} state=${JSON.stringify(state)} viewers=${sessionManager.getRdSessionsForClient(clientId).length}`);
|
logger.info(`[rd-debug] desktop_start reasserting stale stream client=${clientId} lastFrameAgeMs=${Number.isFinite(lastFrameAgeMs) ? lastFrameAgeMs : -1} state=${JSON.stringify(state)} viewers=${sessionManager.getRdSessionsForClient(clientId).length}`);
|
||||||
sendDesktopCommand(target, "desktop_set_fps", { fps: clampDesktopFps(state.maxFps) });
|
sendDesktopCommand(target, "desktop_set_fps", { fps: clampDesktopFps(state.maxFps) });
|
||||||
sendDesktopCommand(target, "desktop_start", {});
|
sendDesktopCommand(target, "desktop_start", {});
|
||||||
|
safeSendViewer(ws, { type: "status", status: "starting" });
|
||||||
state.isStreaming = true;
|
state.isStreaming = true;
|
||||||
state.startedAt = Date.now();
|
state.startedAt = Date.now();
|
||||||
rdStreamingState.set(clientId, state);
|
rdStreamingState.set(clientId, state);
|
||||||
@@ -437,6 +439,7 @@ export function handleRemoteDesktopViewerMessage(ws: ServerWebSocket<SocketData>
|
|||||||
} else {
|
} else {
|
||||||
logger.debug(`[rd] ignoring desktop_stop for client ${clientId} - ${otherViewers.length} other viewer(s) still active`);
|
logger.debug(`[rd] ignoring desktop_stop for client ${clientId} - ${otherViewers.length} other viewer(s) still active`);
|
||||||
}
|
}
|
||||||
|
safeSendViewer(ws, { type: "status", status: "stopped" });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "desktop_record_start": {
|
case "desktop_record_start": {
|
||||||
@@ -994,6 +997,7 @@ export function handleWebcamViewerMessage(ws: ServerWebSocket<SocketData>, raw:
|
|||||||
whepPath: `/api/webrtc/${streamPath}/whep`,
|
whepPath: `/api/webrtc/${streamPath}/whep`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
safeSendViewer(ws, { type: "status", status: "starting" });
|
||||||
sendDesktopCommand(target, "webcam_start", {});
|
sendDesktopCommand(target, "webcam_start", {});
|
||||||
state.isStreaming = true;
|
state.isStreaming = true;
|
||||||
webcamStreamingState.set(clientId, state);
|
webcamStreamingState.set(clientId, state);
|
||||||
@@ -1019,6 +1023,7 @@ export function handleWebcamViewerMessage(ws: ServerWebSocket<SocketData>, raw:
|
|||||||
} else {
|
} else {
|
||||||
logger.debug(`[webcam] ignoring webcam_stop for client ${clientId} - ${otherWebcamViewers.length} other viewer(s) still active`);
|
logger.debug(`[webcam] ignoring webcam_stop for client ${clientId} - ${otherWebcamViewers.length} other viewer(s) still active`);
|
||||||
}
|
}
|
||||||
|
safeSendViewer(ws, { type: "status", status: "stopped" });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "webrtc_p2p_offer": {
|
case "webrtc_p2p_offer": {
|
||||||
|
|||||||
Reference in New Issue
Block a user