using System.Text; using System.Text.Json; using Back.Program.Common.Model; using Back.Program.Models.Entities; using Microsoft.Extensions.Options; using Polly; using Version = System.Version; namespace Back.Program.Services.V1 { public interface IApnsPushService { Task SendPushNotificationAsync(string deviceToken, Payload payload); } public class ApnsPushService: IApnsPushService { private readonly HttpClient _httpClient; private readonly PushFileSetting _setting; public ApnsPushService(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 keys = // JsonSerializer.Deserialize>(await File.ReadAllTextAsync(_setting.p12PWPath)) // ?? throw new FileContentNotFoundException("[푸시] : 파일 내부의 값을 읽어오지 못함"); // // try // { // var handler = new HttpClientHandler(); // handler.ClientCertificates // .Add(new X509Certificate2(_setting.p12Path, keys["Password"])); // handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12; // // // using var client = new HttpClient(handler) // { // BaseAddress = new Uri(_setting.uri), // Timeout = TimeSpan.FromSeconds(60) // }; 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}"); } }); // var response = await client.SendAsync(request); // // if (response.IsSuccessStatusCode) return true; // else // { // var errorContent = await response.Content.ReadAsStringAsync(); // throw new ServiceConnectionFailedException($"[푸시] : APNS 통신 실패 - {errorContent}"); // } // } // catch (HttpRequestException httpEx) // { // Console.WriteLine($"HttpRequestException: {httpEx.Message}"); // throw new ServiceConnectionFailedException($"[푸시] : APNS 통신 실패 - {httpEx.Message}"); // } } } }