using System; using System.Net.Http; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.Json; using System.Threading.Tasks; using AcaMate.V1.Models; using Version = System.Version; public class ApnsPushService { private readonly string _uri; private readonly string _p12Path; private readonly string _p12PWPath; private readonly string _apnsTopic; public ApnsPushService(string uri,string p12Path, string p12PWPath, string apnsTopic) { _uri = uri ?? throw new ArgumentNullException(nameof(uri)); _p12Path = p12Path ?? throw new ArgumentNullException(nameof(p12Path)); _p12PWPath = p12PWPath ?? throw new ArgumentNullException(nameof(p12PWPath)); _apnsTopic = apnsTopic ?? throw new ArgumentNullException(nameof(apnsTopic)); } public async Task SendPushNotificationAsync(string deviceToken, Payload payload) { // 존재 안하면 예외 던져 버리는거 if (!File.Exists(_p12PWPath)) { Console.WriteLine($"File not found: {_p12PWPath}"); return new APIResult { Success = false , Code = "003", Message = "서버 오류 : p12 PW 파일 확인 필요" }; } var jsonPayload = JsonSerializer.Serialize(payload); var keys = JsonSerializer.Deserialize>(File.ReadAllText(_p12PWPath)); var p12Password = keys["Password"]; try { var certificate = new X509Certificate2(_p12Path, p12Password); Console.WriteLine($"Certificate Subject: {certificate.Subject}"); Console.WriteLine($"Certificate Issuer: {certificate.Issuer}"); var handler = new HttpClientHandler(); handler.ClientCertificates.Add(certificate); handler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12; using var client = new HttpClient(handler) { BaseAddress = new Uri(_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", _apnsTopic); request.Headers.Add("apns-push-type", "alert"); Console.WriteLine($"Send -> Payload: {jsonPayload}"); var response = await client.SendAsync(request); if (response.IsSuccessStatusCode) { return new APIResult { Success = true }; } else { var errorContent = await response.Content.ReadAsStringAsync(); return new APIResult { Success = false, Code = "003", Message = $"APN 통신 실패 = {response.StatusCode} : {errorContent}" }; } } catch (HttpRequestException httpEx) { Console.WriteLine($"HttpRequestException: {httpEx.Message}"); return new APIResult { Success = false, Code = "003", Message = $"통신 실패 : {httpEx.Message}" }; } catch (CryptographicException ex) { return new APIResult { Success = false, Code = "999", Message = $"오류 발생 : {ex.Message}" }; } catch (Exception ex) { return new APIResult { Success = false, Code = "999", Message = $"오류 발생 : {ex.Message}" }; } } }