일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 성능
- php
- GCM
- Java
- gcm 푸시 번역
- graphql
- nginx설치
- ddd
- nginx
- GCM 번역
- notification
- JPA
- 웹사이트 성능
- Push
- 웹사이트최적화기법
- 도메인 주도 개발
- 자바스크립트
- 카프카
- 디자인패턴
- 푸시 번역
- 페이스북 번역
- 푸시
- git
- 카프카 트랜잭션
- APNS
- nginx설정
- Design Pattern
- kafka
- 웹사이트성능
Archives
- Today
- Total
간단한 개발관련 내용
[APNs] 10. Appendix B : Legacy Notification Format 본문
Push Notification/APNs
[APNs] 10. Appendix B : Legacy Notification Format
vincenzo.dev.82 2016. 10. 26. 14:31반응형
Legacy Notification Format
APNs 로 연결하기 위한 새로운 개발은 최신의 형식을 사용해야만 하는데요, APNs Provider API 에서 설명했던 것 처럼요.
이 형식들은 priority 를 포함하지 않습니다; 10 의 priority 가 가정되어 있습니다.
Legacy Notification Format
Figure B-1 Legacy notification format
레거시 형식에서 첫 번째 byte 는 0(zero)으로 된 명령어값? 입니다. 다른 속성들은 개선된 형식과 같습니다. B-1 목록은 레거시 알림 형식을 사용해서 바이너리 인터페이스를 통하여 APNs 로의 원격 알림을 보내는 기능의 한 예를 보여줍니다.
Listing B-1 바이너리 인터페이스를 통해 레거시 형식으로 알림을 보내기.
static bool sendPayload(SSL *sslPtr, char *deviceTokenBinary, char *payloadBuff, size_t payloadLength)
{
bool rtn = false;
if (sslPtr && deviceTokenBinary && payloadBuff && payloadLength)
{
uint8_t command = 0; /* command number */
char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint16_t) +
DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];
/* message format is, |COMMAND|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
char *binaryMessagePt = binaryMessageBuff;
uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
uint16_t networkOrderPayloadLength = htons(payloadLength);
/* command */
*binaryMessagePt++ = command;
/* token length network order */
memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* device token */
memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
binaryMessagePt += DEVICE_BINARY_SIZE;
/* payload length network order */
memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* payload */
memcpy(binaryMessagePt, payloadBuff, payloadLength);
binaryMessagePt += payloadLength;
if (SSL_write(sslPtr, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
rtn = true;
}
return rtn; } |
Enhanced Notification Format
개선된 형식은 레거시 형식보다 몇가지 발전된 것들이 있습니다:
- Error response : 레거시 형식처럼, 만약 여러분이 잘못된(malformed) 알림 패킷을 전달한다면, - 예를 들어, 페이로드는 약정한(정해진) 제한을 초과할 것입니다 - APNs 그 연결로 전달하여 응답할 것 입니다. 왜 그 알림이 거부되었는지 어떠한 암시도 주어지지 않습니다. 개선된 형식에는 provider tag 로 임의적인 식별자로 알림을 줍니다. 만약 에러가 발생하면, APNs는 그 식별자와 관련된 에러 코드로 패킷을 반환합니다. 이 응답은 provider 가 위치를 찾아내고 잘못된 알림을 올바르게 할 수 있게 합니다.
- Notification expiration : APNs 는 store-and-forward 방식을 사용하는데 가장 최근 알림을 단말기의 앱으로 보내기 위해 유지 합니다. 만약 단말기가 전달 시점에 오프라인이라면, APNs 는 단말기가 다음 온라인 상태일 때 알림을 전달합니다. 레거시 형식과 같이, 알림은 알림의 적절성과 상관없이 전달되어 집니다. 다른 말로, 알림은 시간이 지남에 따라 “stale” 하게 될 수 있습니다. 개선된 형식은 expiry 값을 포함하는데 이것은 알림의 유효한 기간을 나타냅니다. APNs 는 expiry 기간이 지났을 때 store-and-forward 안에 있는 알림을 제거 합니다.
Figure B-2 알림 패킷들에 대한 형식을 그렸습니다.
알림 형식의 첫 바이트는 1이라는 명령어 값 입니다. 다른 필드들에 대한 설명은 아래와 같습니다:
- Identifier - 알림을 식별 할 수 있는 임의적인 값 입니다. 만약 APNs 가 알림을 해석할 수 없으면 에러-응답 패킷안에 같은 식별자가 반환됩니다.
- Expiry - 초단위로 고정된 UNIX epoch 날짜 표현인데(UTC) 알림이 더 이상 유효하지 않을 때 제거 될 수 있습니다. 만료 값은 network byte order(big endian)을 사용합니다. 만약 expiry 값이 0이 아니라면, APNs는 적어도 한 번 더 알림을 전달하려고 시도할 것 입니다. 요청에 대해 0으로 명히하는 것은 APNs 가 알림 전체를 저장하지 않겠다는 것 입니다.
- Token length - 네트워크 순서(big endian)의 디바이스 토큰 길이.
- Device token - 바이너리 형식의 디바이스 토큰.
Payload length - 네트워크 순서(big endian)의 페이로드 길이. 페이로드는 256 bytes 를 초과해서는 안 되고 null 로 끝나서는 안 됩니다.
- 초기에는 256 bytes 였으나, 현재 iOS 버전은 2KB(2048 bytes) 까지 지원하고 있다.(iOS8 이후부터...)
- Payload - 알림 페이로드.
Listing B-2 바이너리 인터페이스를 통해 개선된 형식으로 알림 보내기.
static bool sendPayload(SSL *sslPtr, char *deviceTokenBinary, char *payloadBuff, size_t payloadLength)
{
bool rtn = false;
if (sslPtr && deviceTokenBinary && payloadBuff && payloadLength)
{
uint8_t command = 1; /* command number */
char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) +
DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];
/* message format is, |COMMAND|ID|EXPIRY|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
char *binaryMessagePt = binaryMessageBuff;
uint32_t whicheverOrderIWantToGetBackInAErrorResponse_ID = 1234;
uint32_t networkOrderExpiryEpochUTC = htonl(time(NULL)+86400); // expire message if not delivered in 1 day
uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
uint16_t networkOrderPayloadLength = htons(payloadLength);
/* command */
*binaryMessagePt++ = command;
/* provider preference ordered ID */
memcpy(binaryMessagePt, &whicheverOrderIWantToGetBackInAErrorResponse_ID, sizeof(uint32_t));
binaryMessagePt += sizeof(uint32_t);
/* expiry date network order */
memcpy(binaryMessagePt, &networkOrderExpiryEpochUTC, sizeof(uint32_t));
binaryMessagePt += sizeof(uint32_t);
/* token length network order */
memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* device token */
memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
binaryMessagePt += DEVICE_BINARY_SIZE;
/* payload length network order */
memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* payload */
memcpy(binaryMessagePt, payloadBuff, payloadLength);
binaryMessagePt += payloadLength;
if (SSL_write(sslPtr, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
rtn = true;
}
return rtn; } |
반응형