From c8ce36a62409f3bc31f45a101518358b1309b835 Mon Sep 17 00:00:00 2001 From: qornwh1 Date: Wed, 4 Mar 2026 16:12:45 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=A4=ED=8C=A8=EC=8B=9C=20=EC=9E=AC=EC=8B=9C=EB=8F=84=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MMOTestServer/MMOserver/Api/RestApi.cs | 51 +++++++++++++++++--------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/MMOTestServer/MMOserver/Api/RestApi.cs b/MMOTestServer/MMOserver/Api/RestApi.cs index bc7a91f..786ab79 100644 --- a/MMOTestServer/MMOserver/Api/RestApi.cs +++ b/MMOTestServer/MMOserver/Api/RestApi.cs @@ -11,29 +11,46 @@ public class RestApi : Singleton private const string VERIFY_URL = "https://a301.api.tolelom.xyz/api/auth/verify"; private readonly HttpClient httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(5) }; - // 토큰 검증 - 성공 시 username 반환, 실패(401/타임아웃 등) 시 null 반환 + private const int MAX_RETRY = 3; + private static readonly TimeSpan RETRY_DELAY = TimeSpan.FromSeconds(1); + + // 토큰 검증 - 성공 시 username 반환 + // 401 → 재시도 없이 즉시 null 반환 (토큰 자체가 무효) + // 타임아웃/네트워크 오류 → 최대 MAX_RETRY회 재시도 후 null 반환 public async Task VerifyTokenAsync(string token) { - try + for (int attempt = 1; attempt <= MAX_RETRY; attempt++) { - HttpResponseMessage response = await httpClient.PostAsJsonAsync(VERIFY_URL, new { token }); - - if (response.StatusCode == HttpStatusCode.Unauthorized) + try { - Log.Warning("[RestApi] 인증 실패 (401)"); - return null; + HttpResponseMessage response = await httpClient.PostAsJsonAsync(VERIFY_URL, new { token }); + + // 401: 토큰 자체가 무효 → 재시도해도 같은 결과, 즉시 반환 + if (response.StatusCode == HttpStatusCode.Unauthorized) + { + Log.Warning("[RestApi] 토큰 인증 실패 (401)"); + return null; + } + + response.EnsureSuccessStatusCode(); + + AuthVerifyResponse? result = await response.Content.ReadFromJsonAsync(); + return result?.Username; + } + catch (Exception ex) when (attempt < MAX_RETRY) + { + // 일시적 장애 (타임아웃, 네트워크 오류 등) → 재시도 + Log.Warning("[RestApi] 통신 실패 (시도 {Attempt}/{Max}): {Message}", attempt, MAX_RETRY, ex.Message); + await Task.Delay(RETRY_DELAY); + } + catch (Exception ex) + { + // 마지막 시도까지 실패 + Log.Error("[RestApi] 최종 통신 실패 ({Max}회 시도): {Message}", MAX_RETRY, ex.Message); } - - response.EnsureSuccessStatusCode(); - - AuthVerifyResponse? result = await response.Content.ReadFromJsonAsync(); - return result?.Username; - } - catch (Exception ex) - { - Log.Error("[RestApi] 웹서버 통신 실패: {Message}", ex.Message); - return null; } + + return null; } private sealed class AuthVerifyResponse