Warning
이 방식은 2019.4.11 이후, 구글 GCM 서비스 종료로, 더 이상 지원이 불가능하니다. 아래 링크를 참고해서, 새로운 버전으로 적용하시기 바랍니다.
Morpheus Push 는 스마트폰 OS에서 지원하는 PNS(Push Notification Server)를 기반으로 한 메세지 전송 플랫폼이다.
Android Client 에서는 UPMC WAS 에서 제공하는 Push API 를 각각 버전 규격에 맞춰 연동하여 원할하게 Push Service 를 운영하기 위한 라이브러리를 제공한다.
– GCM 서비스 등록을 위한 ID
UPMC 3.5 이하 버전
initPushService => 토큰 요청 => User 등록 => Service 등록 => 메시지 수신
UPMC 3.6 이상 버전
initPushService => Service 등록 (자동으로 Token 요청) => User 등록 => 메시지 수신
Android 용 SDK 파일
MPushLibrary
mcore.mobile.lic
– Push 라이센스 정보가 담긴 Push 라이센스 파일
Manifest.xml
– Push 구동을 위한 설정 파일
SDK 적용 방법
Android Project 의 libs 폴더에 Library 파일에 추가
Android Project의 assets/res 폴더에 라이선스 및 설정 파일 추가
MPush 플러그인 파일
MPush.framework
MPush.bundle
플러그인 적용 방법
mcore.mobile.lic
#Tue Feb 17 09:53:27 KST 2015
application_id=xxx.xxx.xxxx.xxxx
expiration_date=xxxx-xx-xx
mpsn=hZK................X
sn=AhA....E....
New in version 3.8.1 Library
Manifest.xml
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<push>
<receiver> <!-- UPMC 설정 정보 -->
<log>y</log>
<!-- key 교환 방식 암호화 : 라이선스 발급시 요청 (hexa코드 16자리) 서버 3.8.1 이상 -->
<security-indexes>0x??? 0x??? 0x??? </security-indexes>
<!-- UPMC 서버 버전 3.6/3.7/3.8/4.0/5.0-->
<version>4.0</version>
<!-- UPMC 서버 url(필수 설정) -->
<server>http://pushxx.morpheus.co.kr:18080/</server>
<timeout>20000</timeout>
<!-- GCM설정 -->
<!-- GCM sender-id (push-type이 GCM일경우 필수설정, sender id가 여러개인 경우, 공백없이 ","로 구분하여 등록한다. ) -->
<gcm-sender-id>xxxxxxxxxxxx,bbbbbbbbbbb</gcm-sender-id>
<!-- 푸쉬타입(필수설정)
GCM:구글GCM(Public Push)
UPNS:유라클UPNS(Private Push)
ALL : Doze Mode 대응 (GCM : Dummy Data, UPNS : real Data)
-->
<android-push-type>GCM</android-push-type>
<!-- 서비스 정책 ,
user : one user multidevice,
device : one user one device,
default : user -->
<policy>device</policy>
<!-- stb(셋탑)/mobile(모바일)/mobile_old(디바이스 아이디 이전 버전) -->
<device-type>mobile</device-type>
<!-- upmc 연동시 휴대폰 번호 사용 여부 -->
<use-phone_number>n</use-phone_number>
<!-- 브로드캐스트 리시버에서 퍼미션 사용 여부를 설정 (Y/N) android 8.0 이상 필수 -->
<use-permission>Y</use-permission>
</receiver>
</push>
</settings>
Key | Type | Description |
---|---|---|
log | String | Push Service 에 대한 Debugging 로그 출력 여부 ( y / n ) |
version | String | UPMC Version ( 3.0, 3.5, 3.6, 3.7, 3.8, 4.0 ) |
server | String | UPMC WAS 서버 URL |
device-type | String | 서비스 디바이스에 대한 성정 (빈값 : mobile, mobile : mobile용, stb : 셋탑용) |
agent-service-type | String | UPNS 서비스 방식 (inapp : 라이브러리형, agent : 별도의 Agent 앱 구현시) |
agent-restart-interval | String | 앱이 살아 있는지 체크를 위한 시간 설정 (단위 : sec) |
agent-receive-confirm | String | upns 메시지 수신 결과에 대한 ack 전송 방법 (auto : 자동 (default), manual : 수동, 직접 구현) |
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="[패키지명]"
android:versionCode="1"
android:versionName="1.0">
<!-- push service&receiver -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- for Gingerbread GSF backward compat -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="[패키지명]" />
</intent-filter>
</receiver>
<service android:name="m.client.push.library.service.GCMInstanceIDListenerService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<receiver android:name="[패키지명].receiver.MessageArrivedReceiver">
<intent-filter>
<action android:name="[패키지명].GCM_MESSAGE_ARRIVED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="[패키지명].receiver.MessageArrivedReceiver">
<intent-filter>
<action android:name="[패키지명].GCM_MESSAGE_ARRIVED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="[패키지명].receiver.PushActionReceiver">
<!--주의 : 오타로 인해, 일부 filter 명이 COMPLETELED 로 정의됨-->
<intent-filter>
<action android:name="[패키지명].REG_PUSHSERVICE_COMPLETELED" />
<action android:name="[패키지명].UNREG_PUSHSERVICE_COMPLETELED" />
<action android:name="[패키지명].REG_SERVICE_AND_USER_COMPLETELED" />
<action android:name="[패키지명].REG_USER_COMPLETELED" />
<action android:name="[패키지명].UNREG_USER_COMPLETELED" />
<action android:name="[패키지명].SEND_MESSAGE_COMPLETELED" />
<action android:name="[패키지명].READ_CONFIRM_COMPLETELED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="m.client.push.library.receiver.GcmActionReceiver">
<intent-filter>
<action android:name="[패키지명].GCM_REG_PUSHSERVICE" />
<action android:name="[패키지명].GCM_UNREG_PUSHSERVICE" />
<action android:name="[패키지명].GCM_REG_SERVICE_AND_USER" />
<action android:name="[패키지명].GCM_UPDATE_PUSHSERVICE_DATE" />
<action android:name="[패키지명].GCM_REG_USER" />
<action android:name="[패키지명].GCM_UNREG_USER" />
<action android:name="[패키지명].GCM_SEND_MESSAGE" />
<action android:name="[패키지명].GCM_READ_CONFIRM" />
<action android:name="[패키지명].GCM_RECEIVE_CONFIRM" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
<!-- GCM & C2DM -->
<permission android:name="[패키지명].permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="[패키지명].permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- 안드로이드 8.0이상 필수 라이브러리 버전 4.1.0.7 이상부터 추가된 리시버 등록 시 권한 등록위해 선언 (없으면 앱 디폴트 권한) -->
<permission android:name="[패키지명].permission.MPUSH_PERMISSION" android:protectionLevel="signature" />
<uses-permission android:name="[패키지명].permission.MPUSH_PERMISSION" />
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="[패키지명]"
android:versionCode="1"
android:versionName="1.0">
<!-- push service&receiver -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- for Gingerbread GSF backward compat -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="[패키지명]" />
</intent-filter>
</receiver>
<service android:name="m.client.push.library.service.GCMIntentService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service android:name="m.client.push.library.service.GCMInstanceIDListenerService" android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<receiver android:name="[패키지명].receiver.MessageArrivedReceiver" >
<intent-filter>
<action android:name="[패키지명].GCM_MESSAGE_ARRIVED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="[패키지명].receiver.PushActionReceiver" >
<intent-filter>
<action android:name="[패키지명].ACTION_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<receiver android:name="m.client.push.library.receiver.GcmActionReceiver" >
<intent-filter>
<action android:name="[패키지명].ACTION_GCM" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
<!-- GCM & C2DM -->
<permission android:name="[패키지명].permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="[패키지명].permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- 안드로이드 8.0이상 필수 라이브러리 버전 4.1.0.7 이상부터 추가된 리시버 등록 시 권한 등록위해 선언 (없으면 앱 디폴트 권한) -->
<permission android:name="[패키지명].permission.MPUSH_PERMISSION" android:protectionLevel="signature" />
<uses-permission android:name="[패키지명].permission.MPUSH_PERMISSION" />
</manifest>
Case #1. Push service 등록
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//앱 실행시점에서 호출 (4.0 )
PushManager.getInstance().initPushServer(getApplicationContext());
//앱 실행 기준, 1일 1회 호출 권장 (3.8 이하)
//앱 실행시마다 호출 (4.0이상)
PushManager.getInstance().registerPushService(getApplicationContext());
...
}
-- Push 플러그인 : http://docs.morpheus.co.kr/client/api/plugin-push.html
Arguments
Arguments
Key | Type | Description |
---|---|---|
PushConstants.KEY_CNAME | String | 사용자 닉네임 |
PushConstants.KEY_STB_ID | String | 셋탑 아이디 |
PushConstants.KEY_DEVICE_ID | String | 디바이스id |
PushConstants.KEY_CUSTOM_RECEIVER_SERVER_URL | String | UPMC url |
PushConstants.KEY_CUSTOM_UPNS_SERVER_URL | String | UPNS url |
- 예시 :
JSONObject params = new JSONObject();
// http://xxx.xxx.x.xx:xxxx 연결할 리시버 서버 url
params.put(PushConstants.KEY_CUSTOM_RECEIVER_SERVER_URL, "http://xxx.xxx.x.xx:xxxx");
// tcp://xxx.xxx.x.xx:xxxx 연결할 UPNS 서버 url
params.put(PushConstants.KEY_CUSTOM_UPNS_SERVER_URL, "tcp://xxx.xxx.x.xx:xxxx");
Arguments
Arguments
Key | Type | Description |
---|---|---|
PushConstants.KEY_DEVICE_ID | String | 디바이스id |
PushConstants.KEY_CUSTOM_RECEIVER_SERVER_URL | String | UPMC url |
PushConstants.KEY_CUSTOM_UPNS_SERVER_URL | String | UPNS url |
- 예시 :
JSONObject params = new JSONObject();
params.put(PushConstants.KEY_STB_ID, "{A73E9E2E-9C6B-11E4-AFAE-C55006B96D3C}");
params.put(PushConstants.KEY_DEVICE_ID, "DEVICE-A73E9E2E9C6B11E4AFAEC55006B96D3C"/*생성하여 추가 요망*/);
params.put(PushConstants.KEY_CNAME, "GUEST-A73E9E2E9C6B11E4AFAEC55006B96D3C");
Arguments
-결과값 : Reciver 를 통해, 처리 결과 통보
Arguments
Key | Type | Necessary | Description |
---|---|---|---|
PushConstants.KEY_CUID | String | 필수 | Client ID |
PushConstants.KEY_CNAME | String | 필수 | Client Name |
PushConstants.KEY_STB_ID | String | 선택 | STB ID |
PushConstants.KEY_DEVICE_ID | String | 선택 | Device ID |
-결과값 : Reciver 를 통해, 처리 결과 통보
Arguments
-결과값 : Reciver 를 통해, 처리 결과 통보
Arguments
Key | Type | Necessary | Description |
---|---|---|---|
PushConstants.KEY_CUID | String | 필수 | Client ID |
PushConstants.KEY_CNAME | String | 필수 | Client Name |
PushConstants.KEY_STB_ID | String | 선택 | STB ID |
PushConstants.KEY_DEVICE_ID | String | 선택 | Device ID |
-결과값 : Reciver 를 통해, 처리 결과 통보
Arguments
-결과값 : Reciver 를 통해, 처리 결과 통보
Arguments
Key | Type | Necessary | Description |
---|---|---|---|
PushConstants.KEY_CUID | String | 필수 | Client ID |
PushConstants.KEY_CNAME | String | 필수 | Client Name |
-결과값 : Reciver 를 통해, 처리 결과 통보
Arguments
-결과값 : Reciver 를 통해, 처리 결과 통보
Arguments
Key | Type | Necessary | Description |
---|---|---|---|
PushConstants.KEY_CNAME | String | 선택 | Client Name |
PushConstants.KEY_STB_ID | String | 선택 | STB ID |
PushConstants.KEY_DEVICE_ID | String | 선택 | Device ID |
- 예시 :
JSONObject params = new JSONObject();
params.put(PushConstants.KEY_STB_ID, "{A73E9E2E-9C6B-11E4-AFAE-C55006B96D3C}");
params.put(PushConstants.KEY_DEVICE_ID, "DEVICE-A73E9E2E9C6B11E4AFAEC55006B96D3C");
Arguments
New in version 4.0 UPMC
Arguments
Key | Type | Description |
---|---|---|
PushConstants.BADGE_TYPE_KEEP | String | 1개 읽음 처리, 다음 메시지 수신시, 동일한 값 유지(Default, -1 후 +1 이 됨) |
PushConstants.BADGE_TYPE_RESET | String | 입력 값으로 초기화, 다음 수신된 값은 입력값 +1로 처리됨 |
PushConstants.BADGE_TYPE_UPDATE | String | 카운트에 따라 업데이트 됨 (읽음여부에 상관없이, push 수신 ++) |
Arguments
Arguments
Arguments
Arguments
Arguments
Arguments
Arguments
Key | Description (결과값) |
---|---|
PushConstantsEx.COMPLETE_BUNDLE.REG_USER | 사용자 등록 |
PushConstantsEx.COMPLETE_BUNDLE.UNREG_USER | 사용자 등록 |
PushConstantsEx.COMPLETE_BUNDLE.UPDATE_PUSHSERVICE_DATE | push service 갱신 |
PushConstantsEx.COMPLETE_BUNDLE.REG_PUSHSERVICE | 푸시 서비스 등록 |
PushConstantsEx.COMPLETE_BUNDLE.UNREG_PUSHSERVICE | 푸시 서비스 해제 |
PushConstantsEx.COMPLETE_BUNDLE.READ_CONFIRM | 읽음 ack |
PushConstantsEx.COMPLETE_BUNDLE.RECEIVE_CONFIRM | 수신 ack (gcm only) |
PushConstantsEx.COMPLETE_BUNDLE.IS_REGISTERED_SERVICE | 서비스 등록 여부 (register service 호출 시, 수신 될 수 있음) |
PushConstantsEx.COMPLETE_BUNDLE.INITBADGENO | 뱃지 넘버 초기화 |
PushConstantsEx.COMPLETE_BUNDLE.REG_GROUP | 그룹 등록 |
PushConstantsEx.COMPLETE_BUNDLE.UNREG_GROUP | 그릅 해제 |
Key | Description (결과값) |
---|---|
PushConstants.RESULTCODE_OK | 정상 |
PushConstants.RESULTCODE_HTTP_ERR | 통신 오류 - UPMC서버에 접속할 수 없을때 - connection 관련 error |
PushConstants.RESULTCODE_AUTHKEY_ERR | 인증키 획득 오류 |
PushConstants.RESULTCODE_RESPONSE_ERR | 응답 오류 - 오류코드를 수신한 경우 |
PushConstants.RESULTCODE_INTERNAL_ERR | 정의되지 않은 예기치 못한 오류가 발생한 경우 |
PushConstants.RESULTCODE_AUTHKEY_ERR2 | 인증키 획득 오류 |
Key | Description (결과값) |
---|---|
PushConstants.KEY_RESULT | ACTION_COMPLETED에 Extras용 전체 호출값 |
PushConstants.KEY_BUNDLE | 번들용 KEY |
PushConstants.KEY_ISREGISTER | 서비스 등록 여부에 대한 결과값 |
PushConstants.KEY_RESULT_CODE | 결과 코드 (정상 : 200) |
PushConstants.KEY_RESULT_MSG | upmc 통신 이후, 수신된 메시지 |
private BroadcastReceiver mLoginBroadcastReceiver;
public void registerReceiver() {
if (mLoginBroadcastReceiver != null) {
return;
}
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(LoginActivity.this.getPackageName() + PushConstantsEx.ACTION_COMPLETED);
mLoginBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(!PushUtils.checkValidationOfCompleted(intent, context)){
return;
}
//intent 정보가 정상적인지 판단
String result = intent.getExtras().getString(PushConstants.KEY_RESULT);
String bundle = intent.getExtras().getString(PushConstantsEx.KEY_BUNDLE);
JSONObject result_obj = null;
String resultCode = "";
String resultMsg = "";
try {
result_obj = new JSONObject(result);
resultCode = result_obj.getString(PushConstants.KEY_RESULT_CODE);
resultMsg = result_obj.getString(PushConstants.KEY_RESULT_MSG);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Action에 따라 분기 (이미 서비스 등록이 된 경우 다음 process 이동)
if(bundle.equals(PushConstantsEx.COMPLETE_BUNDLE.REG_USER)) {
if (resultCode.equals(PushConstants.SUCCESS_RESULT_CODE)) {
Toast.makeText(context, "로그인 성공!", Toast.LENGTH_SHORT).show();
setSendTest();
}else {
Toast.makeText(context, "[LoginActivity] error code: " + resultCode + " msg: " + resultMsg, Toast.LENGTH_SHORT).show();
}
}else if (bundle.equals(PushConstantsEx.COMPLETE_BUNDLE.UNREG_PUSHSERVICE)) {
if (resultCode.equals(PushConstants.SUCCESS_RESULT_CODE)) {
Toast.makeText(context, "해제 성공!", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "[LoginActivity] error code: " + resultCode + " msg: " + resultMsg, Toast.LENGTH_SHORT).show();
}
}else if (bundle.equals(PushConstantsEx.COMPLETE_BUNDLE.REG_GROUP)) {
if (resultCode.equals(PushConstants.SUCCESS_RESULT_CODE)) {
Toast.makeText(context, "그룹 등록 성공!", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "[LoginActivity] error code: " + resultCode + " msg: " + resultMsg, Toast.LENGTH_SHORT).show();
}
}else if (bundle.equals(PushConstantsEx.COMPLETE_BUNDLE.UNREG_GROUP)) {
if (resultCode.equals(PushConstants.SUCCESS_RESULT_CODE)) {
Toast.makeText(context, "그룹 해제 성공!", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "[LoginActivity] error code: " + resultCode + " msg: " + resultMsg, Toast.LENGTH_SHORT).show();
}
}else if (bundle.equals(PushConstantsEx.COMPLETE_BUNDLE.REG_SERVICE_AND_USER)) {
if (resultCode.equals(PushConstants.SUCCESS_RESULT_CODE)) {
Toast.makeText(context, "로그인 성공!", Toast.LENGTH_SHORT).show();
setSendTest();
}else {
Toast.makeText(context, "[LoginActivity] error code: " + resultCode + " msg: " + resultMsg, Toast.LENGTH_SHORT).show();
}
}else if (bundle.equals(PushConstantsEx.COMPLETE_BUNDLE.INITBADGENO)) {
if (resultCode.equals(PushConstants.SUCCESS_RESULT_CODE)) {
Toast.makeText(context, "Badge Number 초기화 성공 !", Toast.LENGTH_SHORT).show();
PushManager.getInstance().setDeviceBadgeCount(getApplicationContext(), "11");
}else {
Toast.makeText(context, "[LoginActivity] error code: " + resultCode + " msg: " + resultMsg, Toast.LENGTH_SHORT).show();
}
}else if(bundle.equals(PushConstantsEx.COMPLETE_BUNDLE.IS_REGISTERED_SERVICE)){
String isRegister = "";
try {
isRegister = result_obj.getString(PushConstants.KEY_ISREGISTER);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(isRegister.equals("C")){
Toast.makeText(context, "CHECK ON [ 사용자 재등록 필요 !! ]", Toast.LENGTH_LONG ).show();
}else if(isRegister.equals("N")){
Toast.makeText(context, "CHECK ON [ 서비스 재등록 필요 !! ]", Toast.LENGTH_LONG).show();
}else{
Logger.i("서비스 정상 등록 상태 ");
}
}
}
};
// use-permission 설정에 따라 리시버 등록 API를 구분한다.
PushConfigInfo config = PushManager.getInstance().getPushConfigInfo(this);
if (config.usePermission()) {
// 리시버 권한 사용 시
this.registerReceiver(mLoginBroadcastReceiver, intentFilter, this.getPackageName()+PushConstants.PERMISSION_PUSHSERVICE, null);
}
else {
// 리시버 권한 미사용 시
this.registerReceiver(mLoginBroadcastReceiver, intentFilter);
}
}
public void unregisterReceiver() {
if (mLoginBroadcastReceiver != null) {
this.unregisterReceiver(mLoginBroadcastReceiver);
mLoginBroadcastReceiver = null;
}
}
아래 기술된 메시지는 샘플에 대한 예시이며, 프로젝트에서 표현하고자 하는 방식에 따라, Interface 정의서에 의해, 변경이 가능함.
JSONObject key 값에 대한 설명 [key가 소문자임]
Key | 활용방법 |
---|---|
alert | 메시지 타이틀로 이용 |
alert.aif | 수신음 파일명 (적용여부는 상황에 맞게 판단) |
ext | 일반 메시지인 경우, 메시지로 이용가능하며, Rich 메시지인 경우, 세부 정보를 추가로 획득하여, 표현 |
seqno | Push message의 고유 키값 |
appid | Push 서비스가 관리되는 앱 ID ( Application ID) |
sender | 발송자 코드 (서버관점) |
senddate | 발송된 시간 (서버관점) |
db_in | DB에 저장 여부 (서버 관점) |
badge | 뱃지값 |
pushkey | public push의 토큰 유효성을 위해 관리되는 키 (서버관점) |
{
"aps":{
"badge":"14",
"sound":"alert.aif",
"alert":"일반 알림"
},
"mps":{
"appid":"com.uracle.push.test",
"ext":"메세지 테스트",
"seqno":"288",
"sender":"device-android",
"senddate":"2016041409",
"db_in":"Y",
"pushkey":"2427efdf1b62cd9dbdf174bbdff048f8051461e1"
}
}
{
"aps":{
"badge":"15",
"sound":"alert.aif",
"alert":"Web 알림"
},
"mps":{
"appid":"com.uracle.push.test",
"ext"::”1|웹페이지|http://lab.morpheus.kr/push/sample/image|http://lab.morpheus.kr/push/sample/webpage”,
"seqno":"290",
"sender":"device-android",
"senddate":"2016041409",
"db_in":"Y",
"pushkey":"2427efdf1b62cd9dbdf174bbdff048f8051461e1"
}
}
{
"aps":{
"badge":"16",
"sound":"alert.aif",
"alert":"동영상 알림"
},
"mps":{
"appid":"com.uracle.push.test",
"ext":”2|기본동영상|http://lab.morpheus.kr/push/sample/image|https://youtu.be/IIu0VMdOe10”,
"seqno":"292",
"sender":"device-android",
"senddate":"2016041409",
"db_in":"Y",
"pushkey":"2427efdf1b62cd9dbdf174bbdff048f8051461e1"
}
}
{
"aps":{
"badge":"17",
"sound":"alert.aif",
"alert":"이미지 알림"
},
"mps":{
"appid":"com.uracle.push.test",
"ext":”3|기본이미지|http://lab.morpheus.kr/push/sample/image”,
"seqno":"294",
"sender":"device-android",
"senddate":"2016041409",
"db_in":"Y",
"pushkey":"2427efdf1b62cd9dbdf174bbdff048f8051461e1"
}
}
GCM:
android.googleapis.com 443,5228,5229,5230
FCM:
fcm.googleapis.com 443,5228,5229,5230
FCM 포트 및 방화벽:
조직에 인터넷 트래픽 송수신을 제한하는 방화벽이 있으면 모바일 기기의 FCM 연결을 허용하도록 구성해야 네트워크의 기기에서 메시지를 수신할 수 있습니다. FCM은 대개 포트 5228을 사용하지만 5229 및 5230을 사용하는 경우도 있습니다.
발신 연결의 경우 Google IP 범위가 매우 자주 변경되며 개발자의 방화벽 규칙이 오래되면 사용자 경험에 영향을 줄 수 있으므로 FCM에서 특정 IP를 제공하지 않습니다. IP 제한 없이 포트 5228~5230을 허용하는 것이 가장 좋습니다. 하지만 IP 제한이 있어야 한다면 Google ASN 15169에 나와 있는 IPv4 및 IPv6 블록의 모든 IP 주소를 허용해야 합니다. 목록의 크기가 크며 규칙을 매월 업데이트하도록 계획을 세워야 합니다. 방화벽 IP 제한으로 인해 발생하는 문제는 보통 간헐적이며 진단하기 어렵습니다.
수신 메시지용으로 열어야 하는 포트:
5228
5229
5230
발신 연결을 허용하는 포트:
다음 중 하나(1번 옵션 권장):
1. IP 제한 없음
2. Google ASN 15169 에 나와 있는 IP 블록에 포함된 모든 IP 주소: 한 달에 한 번 이상 업데이트해야 합니다.