FeedBackService
:메시지전달 실패에 대한 정보를 제공하는 서비스이다.
- 특정 장비에서 이미 삭제된 애플리케이션으로 Push 메시지를 전달하려고 시도할 경우 해당 장비는 Push 메시지 수신을 거부한다.
- 원격알림을 전송할 수 없는 디바이스 토큰을 피드백리스트 목록에 올려놓는다.
- 전송실패 혹은 오류에 대한 알림은 피드백서비스에 영향을 미치지 않는다.
- feedback.push.apple.com의 도메인과 2196포트로의 연결을 통해 피드백서비스를 사용할 수 있다.
(개발서버는 feeback.sandbox.push.apple.com/2196으로 연결한다.)
- 피드백서비스를 사용하여 전달할 수없는 원격 알림 전송을 중지하면 불필요한 메시지 오버 헤드가 줄어들고 전체 시스템 성능을 향상 할 수 있다.
- end-to-end의 TLS/SSL 연결만이 허용된다.
-개발서버에서 어플에 해당하는 인증서를 갖고 피드백 서비스에 연결하면 즉시 피드백 서비스에서 리스트업 된 디바이스 토큰 정보가 포함된 데이터를 전송한다.(연결 후 서버에서 따로 해 주어야 할 내용은 없다)
- 피드백 서비스에서 저장된 디바이스 토큰 리스트의 데이터를 다 받게 되면 서비스 내의 토큰들은 모두 삭제된다.
-개발자 문서에서는 적어도 하루에 한번 피드백 서비스를 확인하라고 명시되어 있으며 상황에 따라 유동적으로 확인이 필요하다.
- 어떠한 요청도 보낼 필요 없이, 연결 즉시 응답이 오며 Connection은 종료된다.
Format
Timestmap : 데이터에 포함된 타임스탬프 정보를 갖고 서버에 저장된 디바이스 토큰의 갱신여부를 판단할 수 있다.
Token Lenth : 디바이스 토큰의 길이
device Token : 디바이스 토큰 값
예제
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.net.UnknownHostException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.Arrays; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; public class Main { public static void main(String[] args) { BufferedInputStream bis = null; SSLSocket feedSock = null; try { KeyStore ks = null; ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream("path.."), "password".toCharArray()); System.out.println("key size:" + ks.size() + "/key type:" + ks.getType()); /// SUNX 509 or PKIX // 인증서 인코딩 알고리즘 KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509"); kmf.init(ks, "password..".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("sunx509"); tmf.init((KeyStore) null); // TLS or SSL protocol get SSLContext sc = SSLContext.getInstance("TLS"); // SSLContext sc = SSLContext.getInstance("SSL"); sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); SSLSocketFactory ssf = sc.getSocketFactory(); feedSock = (SSLSocket) ssf.createSocket("feedback.sandbox.push.apple.com", 2196); String[] cipherSuites = feedSock.getSupportedCipherSuites(); feedSock.setEnabledCipherSuites(cipherSuites); // TLS HandShake feedSock.startHandshake(); ; System.out.println("피드백 서비스 연결:" + feedSock.isConnected()); int a = 0; bis = new BufferedInputStream(feedSock.getInputStream()); while (true) { byte[] tuple = new byte[38]; a = bis.read(tuple, 0, tuple.length); System.out.println(a); byte[] time_t = Arrays.copyOfRange(tuple, 0, 4); byte[] token_length = Arrays.copyOfRange(tuple, 4, 6); byte[] token = Arrays.copyOfRange(tuple, 6, tuple.length); if (a > 0) { // System.out.println("time_t:" + byteArrayToInt(time_t)); // System.out.println("token_length:" + byteArrayToInt(token_length)); // System.out.println("token:" + byteArrayToHex(token)); } else { break; } } } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (KeyStoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (KeyManagementException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CertificateException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnrecoverableKeyException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { bis.close(); feedSock.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } | cs |
'Cloud & NoSQL & Middleware > Apns' 카테고리의 다른 글
Binary Provider API 구현 (0) | 2018.06.11 |
---|---|
HTTP/2 - based Apns Provider API (0) | 2018.05.31 |
Binary Provider API - Request, Response Format (0) | 2018.05.25 |
APNS Provider Protocol (0) | 2018.05.25 |
APNS Notification Payload (0) | 2018.05.15 |