Skip to content

Commit e06e01f

Browse files
committed
fix: 앱 백그라운드에서 실행
1 parent acf92ac commit e06e01f

File tree

2 files changed

+123
-15
lines changed

2 files changed

+123
-15
lines changed

Assets/Infrastructure/Auth/OAuth2/Handlers/DesktopCallbackHandler.cs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class DesktopCallbackHandler : IOAuth2CallbackHandler
2020
private HttpListener _listener;
2121
private CancellationTokenSource _cancellationTokenSource;
2222
private string _callbackUrl;
23+
private DateTime _lastActivityTime;
24+
private bool _isWaitingForCallback = false;
2325

2426
public string PlatformName => "Desktop";
2527
public bool IsSupported => true;
@@ -30,6 +32,10 @@ public async Task InitializeAsync(string expectedState, float timeoutSeconds)
3032
_timeoutSeconds = timeoutSeconds;
3133
_isInitialized = true;
3234
_cancellationTokenSource = new CancellationTokenSource();
35+
_lastActivityTime = DateTime.UtcNow;
36+
37+
// Unity 이벤트 등록
38+
Application.focusChanged += OnApplicationFocusChanged;
3339

3440
// 로컬 HTTP 서버 시작
3541
await StartLocalServerAsync();
@@ -45,6 +51,7 @@ public async Task<string> WaitForCallbackAsync()
4551
}
4652

4753
Debug.Log("[DesktopCallbackHandler] OAuth2 콜백 대기 시작");
54+
_isWaitingForCallback = true;
4855

4956
var startTime = DateTime.UtcNow;
5057
var timeout = TimeSpan.FromSeconds(_timeoutSeconds);
@@ -54,23 +61,38 @@ public async Task<string> WaitForCallbackAsync()
5461
if (!string.IsNullOrEmpty(_callbackUrl))
5562
{
5663
Debug.Log($"[DesktopCallbackHandler] OAuth2 콜백 수신: {_callbackUrl}");
64+
_isWaitingForCallback = false;
5765
return _callbackUrl;
5866
}
5967

60-
// 100ms 대기
61-
await UniTask.Delay(100);
68+
// 앱이 포커스를 잃었을 때 더 자주 체크
69+
var checkInterval = Application.isFocused ? 100 : 50; // 백그라운드일 때 더 빠르게 체크
70+
await UniTask.Delay(checkInterval);
71+
72+
// 디버그 정보 출력 (10초마다)
73+
if ((DateTime.UtcNow - _lastActivityTime).TotalSeconds >= 10)
74+
{
75+
Debug.Log($"[DesktopCallbackHandler] 콜백 대기 중... (경과: {(DateTime.UtcNow - startTime).TotalSeconds:F1}초, 포커스: {Application.isFocused})");
76+
_lastActivityTime = DateTime.UtcNow;
77+
}
6278
}
6379

6480
Debug.LogWarning("[DesktopCallbackHandler] OAuth2 콜백 타임아웃");
81+
_isWaitingForCallback = false;
6582
return null;
6683
}
6784

6885
public void Cleanup()
6986
{
7087
_isDisposed = true;
88+
_isWaitingForCallback = false;
7189
_cancellationTokenSource?.Cancel();
7290
_listener?.Stop();
7391
_listener?.Close();
92+
93+
// Unity 이벤트 해제
94+
Application.focusChanged -= OnApplicationFocusChanged;
95+
7496
Debug.Log("[DesktopCallbackHandler] 정리 완료");
7597
}
7698

@@ -236,5 +258,41 @@ private async Task ProcessCallbackAsync(HttpListenerContext context)
236258
Debug.LogError($"[DesktopCallbackHandler] 콜백 처리 중 오류: {ex.Message}");
237259
}
238260
}
261+
262+
/// <summary>
263+
/// 앱 포커스 변경 이벤트 처리
264+
/// </summary>
265+
private void OnApplicationFocusChanged(bool hasFocus)
266+
{
267+
if (_isWaitingForCallback)
268+
{
269+
Debug.Log($"[DesktopCallbackHandler] 앱 포커스 변경: {hasFocus}");
270+
271+
if (hasFocus)
272+
{
273+
// 앱이 다시 포커스를 받았을 때 콜백 URL 확인
274+
CheckForCallbackUrl();
275+
}
276+
}
277+
}
278+
279+
/// <summary>
280+
/// 콜백 URL 확인 (앱 포커스 복귀 시)
281+
/// </summary>
282+
private void CheckForCallbackUrl()
283+
{
284+
try
285+
{
286+
// 로컬 서버에서 최근 요청 확인
287+
if (_listener != null && _listener.IsListening)
288+
{
289+
Debug.Log("[DesktopCallbackHandler] 앱 포커스 복귀 - 콜백 URL 재확인");
290+
}
291+
}
292+
catch (Exception ex)
293+
{
294+
Debug.LogError($"[DesktopCallbackHandler] 콜백 URL 확인 중 오류: {ex.Message}");
295+
}
296+
}
239297
}
240298
}

Assets/Infrastructure/Auth/OAuth2/ServerOAuth2Provider.cs

Lines changed: 63 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ public ServerOAuth2Provider(ServerOAuth2Config config)
4040

4141
Debug.Log($"[ServerOAuth2Provider] HttpApiClient 초기화 상태: {_httpClient.IsInitialized}");
4242

43+
// Unity 백그라운드 실행 설정
44+
Application.runInBackground = true;
45+
Debug.Log("[ServerOAuth2Provider] 백그라운드 실행 활성화");
46+
4347
// 플랫폼별 콜백 핸들러 생성
4448
_callbackHandler = OAuth2CallbackHandlerFactory.CreateHandler();
4549
Debug.Log($"[ServerOAuth2Provider] {_callbackHandler.PlatformName} 콜백 핸들러 생성됨");
@@ -318,6 +322,12 @@ public async Task<TokenSet> LoginWithServerOAuth2Async(string scope)
318322
try
319323
{
320324
Debug.Log("[ServerOAuth2Provider] 전체 OAuth2 로그인 플로우 시작");
325+
Debug.Log("=== 🔐 OAuth2 로그인 시작 ===");
326+
Debug.Log("1. 브라우저가 열립니다.");
327+
Debug.Log("2. Google 로그인을 완료해주세요.");
328+
Debug.Log("3. 로그인 완료 후 Unity 앱으로 돌아와주세요.");
329+
Debug.Log("4. 콜백을 자동으로 처리합니다.");
330+
Debug.Log("================================");
321331

322332
// 1. PKCE 파라미터 생성
323333
var pkce = await GeneratePKCEAsync();
@@ -332,16 +342,21 @@ public async Task<TokenSet> LoginWithServerOAuth2Async(string scope)
332342
throw new InvalidOperationException($"브라우저 열기 실패: {browserResult.Error}");
333343
}
334344

345+
Debug.Log("✅ 브라우저가 열렸습니다. Google 로그인을 진행해주세요.");
346+
335347
// 4. 콜백 대기 및 처리
336348
var callbackResult = await WaitForOAuth2CallbackAsync(pkce.State);
337349
if (!callbackResult.success)
338350
{
339351
throw new InvalidOperationException("OAuth2 콜백 처리 실패");
340352
}
341353

354+
Debug.Log("✅ OAuth2 콜백 수신 완료. 토큰을 요청합니다.");
355+
342356
// 5. 토큰 요청
343357
var tokenSet = await RequestTokenAsync(callbackResult.state);
344358

359+
Debug.Log("=== 🔐 OAuth2 로그인 완료 ===");
345360
Debug.Log("[ServerOAuth2Provider] 전체 OAuth2 로그인 플로우 완료");
346361
return tokenSet;
347362
}
@@ -404,14 +419,30 @@ private async Task<OAuth2BrowserResult> OpenOAuth2BrowserAsync(string authUrl)
404419
Application.OpenURL(authUrl);
405420
browserType = "Default Browser";
406421
#else
407-
// 데스크톱에서는 기본 브라우저 사용
408-
Application.OpenURL(authUrl);
409-
browserType = "Default Browser";
422+
// 데스크톱에서는 기본 브라우저 사용 (백그라운드에서 실행)
423+
try
424+
{
425+
// Windows에서 백그라운드로 브라우저 열기
426+
var process = new System.Diagnostics.Process();
427+
process.StartInfo.FileName = authUrl;
428+
process.StartInfo.UseShellExecute = true;
429+
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
430+
process.Start();
431+
432+
Debug.Log("[ServerOAuth2Provider] 브라우저가 백그라운드에서 열렸습니다.");
433+
}
434+
catch (Exception ex)
435+
{
436+
Debug.LogWarning($"[ServerOAuth2Provider] 백그라운드 브라우저 열기 실패, 기본 방식 사용: {ex.Message}");
437+
Application.OpenURL(authUrl);
438+
}
439+
browserType = "Background Browser";
410440
#endif
411441

412-
// 브라우저 열기 대기
413-
await UniTask.Delay(1000);
442+
// 브라우저 열기 대기 (더 짧게)
443+
await UniTask.Delay(500);
414444

445+
Debug.Log("[ServerOAuth2Provider] 브라우저 열기 완료 - 콜백 대기 시작");
415446
return OAuth2BrowserResult.SuccessResult(authUrl, platform, browserType);
416447
}
417448
catch (Exception ex)
@@ -431,24 +462,43 @@ private async Task<OAuth2BrowserResult> OpenOAuth2BrowserAsync(string authUrl)
431462
try
432463
{
433464
Debug.Log($"[ServerOAuth2Provider] OAuth2 콜백 대기 시작 - State: {expectedState}");
465+
Debug.Log("[ServerOAuth2Provider] 브라우저에서 OAuth2 로그인을 완료한 후 Unity 앱으로 돌아와주세요.");
434466

435467
// 콜백 핸들러 초기화
436468
await _callbackHandler.InitializeAsync(expectedState, _config.TimeoutSeconds);
437469

438-
// 콜백 대기
439-
var callbackUrl = await _callbackHandler.WaitForCallbackAsync();
470+
// 콜백 대기 (더 강화된 로직)
471+
var startTime = DateTime.UtcNow;
472+
var timeout = TimeSpan.FromSeconds(_config.TimeoutSeconds);
440473

441-
if (!string.IsNullOrEmpty(callbackUrl))
474+
while (DateTime.UtcNow - startTime < timeout)
442475
{
443-
var result = await HandleOAuth2CallbackAsync(callbackUrl);
444-
if (result.success && result.state == expectedState)
476+
// 앱이 포커스를 잃었을 때 더 자주 체크
477+
var checkInterval = Application.isFocused ? 200 : 100;
478+
await UniTask.Delay(checkInterval);
479+
480+
// 콜백 핸들러에서 URL 확인
481+
var callbackUrl = await _callbackHandler.WaitForCallbackAsync();
482+
483+
if (!string.IsNullOrEmpty(callbackUrl))
484+
{
485+
var result = await HandleOAuth2CallbackAsync(callbackUrl);
486+
if (result.success && result.state == expectedState)
487+
{
488+
Debug.Log("[ServerOAuth2Provider] OAuth2 콜백 수신 완료");
489+
return result;
490+
}
491+
}
492+
493+
// 디버그 정보 출력 (5초마다)
494+
var elapsed = (DateTime.UtcNow - startTime).TotalSeconds;
495+
if (elapsed % 5 < 0.2) // 5초마다
445496
{
446-
Debug.Log("[ServerOAuth2Provider] OAuth2 콜백 수신 완료");
447-
return result;
497+
Debug.Log($"[ServerOAuth2Provider] 콜백 대기 중... (경과: {elapsed:F1}초, 포커스: {Application.isFocused})");
448498
}
449499
}
450500

451-
Debug.LogError("[ServerOAuth2Provider] OAuth2 콜백 타임아웃 또는 실패");
501+
Debug.LogError("[ServerOAuth2Provider] OAuth2 콜백 타임아웃");
452502
return (false, null);
453503
}
454504
catch (Exception ex)

0 commit comments

Comments
 (0)