From 39a8f03b591b8dd2747ca9999b432da4f3b4f00e Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 05:02:50 +0000 Subject: [PATCH] =?UTF-8?q?=EC=9B=90=EA=B2=A9=EA=B4=80=EB=A6=AC:=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0=20=EB=81=8A=EA=B8=B0=20=ED=9B=84=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20=EB=A7=89=EB=8C=80=EA=B0=80=20=EB=82=A8=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 화면 프레임 전송을 화면 중지 토큰으로 취소하지 않음 (TLS 스트림 손상 방지) - screenStop/연결 종료/[연결 끊기] 시 표시 막대 즉시 갱신 (EndScreen) - Passive 수신을 켠 적이 없으면 시작 시 "Passive 수신 중지" 로그 생략 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013U497kUNL8ArhV7jkzCpKa --- Core/Remote/RemoteClient.cs | 3 ++- Core/Remote/RemoteServer.cs | 24 ++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/Core/Remote/RemoteClient.cs b/Core/Remote/RemoteClient.cs index 03c1e28..a04e09a 100644 --- a/Core/Remote/RemoteClient.cs +++ b/Core/Remote/RemoteClient.cs @@ -456,11 +456,12 @@ namespace JJServiceManager.Remote var key = enabled ? $"{mode}|{port}" : "off"; if (key == _key) return; _key = key; + bool wasRunning = _listener != null; _listener?.Dispose(); _listener = null; if (!enabled) { - _log("Passive 수신 중지", LogLevel.Info); + if (wasRunning) _log("Passive 수신 중지", LogLevel.Info); return; } try diff --git a/Core/Remote/RemoteServer.cs b/Core/Remote/RemoteServer.cs index 22ef654..fa8c33b 100644 --- a/Core/Remote/RemoteServer.cs +++ b/Core/Remote/RemoteServer.cs @@ -399,7 +399,7 @@ namespace JJServiceManager.Remote } } var old = Interlocked.Exchange(ref screen, null); - old?.Stop(); + EndScreen(old); var s = new ScreenSession(Interlocked.Increment(ref _nextScreenId), whoNow, control, monitor); screen = s; _screens[s.Id] = s; @@ -425,7 +425,7 @@ namespace JJServiceManager.Remote case "screenStop": { var s = Interlocked.Exchange(ref screen, null); - s?.Stop(); + EndScreen(s); await Reply(conn, id, result: new JsonObject()); break; } @@ -473,7 +473,7 @@ namespace JJServiceManager.Remote streams.Clear(); } var s = Interlocked.Exchange(ref screen, null); - s?.Stop(); + EndScreen(s); conn.Dispose(); if (authed && who != peer) _log($"원격 연결 종료: {who}", LogLevel.Info); } @@ -544,7 +544,7 @@ namespace JJServiceManager.Remote ["w"] = w, ["h"] = h, ["data"] = Convert.ToBase64String(jpeg) - }, s.Token).ConfigureAwait(false); + }, ct).ConfigureAwait(false); // 보내는 도중 취소하면 TLS 스트림이 깨지므로 화면 중지 토큰은 쓰지 않음 lastHash = hash; lastMonitor = monitor; lastSent = DateTime.UtcNow; @@ -564,7 +564,11 @@ namespace JJServiceManager.Remote _screens.TryRemove(s.Id, out _); if (!conn.IsDisposed) { - try { await conn.SendAsync(new JsonObject { ["event"] = "screenEnd", ["sid"] = s.Id, ["reason"] = endReason }).ConfigureAwait(false); } + try + { + using var t = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + await conn.SendAsync(new JsonObject { ["event"] = "screenEnd", ["sid"] = s.Id, ["reason"] = endReason }, t.Token).ConfigureAwait(false); + } catch { } } _log($"[원격 화면] {s.Who} 연결 끝", LogLevel.Info); @@ -572,10 +576,18 @@ namespace JJServiceManager.Remote } } + /// 화면 연결 하나 끝내기 — 표시 막대는 바로 갱신 + private void EndScreen(ScreenSession s) + { + if (s == null) return; + s.Stop(); + if (_screens.TryRemove(s.Id, out _)) NotifyViewers(); + } + /// 이 PC에서 [연결 끊기]를 눌렀을 때 모든 화면 연결 종료 public void StopAllScreens() { - foreach (var s in _screens.Values) s.Stop(); + foreach (var s in _screens.Values.ToList()) EndScreen(s); } private void NotifyViewers()