using System.Text; using System.Text.Json; using Back.Program.Common.Model; using Back.Program.Models.Entities; using Back.Program.Services.V1.Interfaces; using Microsoft.Extensions.Options; using Polly; using Version = System.Version; namespace Back.Program.Services.V1 { public class PushService: IPushService { private readonly HttpClient _httpClient; private readonly PushFileSetting _setting; public PushService(HttpClient httpClient, IOptions options) { _httpClient = httpClient; _setting = options.Value; } public async Task SendPushNotificationAsync(string deviceToken, Payload payload) { // 존재 안하면 예외 던져 버리는거 if (!File.Exists(_setting.p12Path) || !File.Exists(_setting.p12PWPath)) throw new FileNotFoundException("[푸시] : p12 관련 파일 확인 필요"); var jsonPayload = JsonSerializer.Serialize(payload); var request = new HttpRequestMessage(HttpMethod.Post, $"/3/device/{deviceToken}") { Content = new StringContent(jsonPayload, Encoding.UTF8, "application/json"), Version = new Version(2, 0) // HTTP/2 사용 }; // 필수 헤더 추가 request.Headers.Add("apns-topic", _setting.apnsTopic); request.Headers.Add("apns-push-type", "alert"); var policy = Policy.Handle() .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); await policy.ExecuteAsync(async () => { var response = await _httpClient.SendAsync(request); if (!response.IsSuccessStatusCode) { var errorContent = await response.Content.ReadAsStringAsync(); throw new ServiceConnectionFailedException($"[푸시] : APNS 통신 실패 - {errorContent}"); } }); } } }