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, 04);
                byte[] token_length = Arrays.copyOfRange(tuple, 46);
                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

+ Recent posts