본문 바로가기

개발도구/aOS - 안드로이드 개발

[PHP] 안드로이드 c2dm 푸시 사용하기

펌) http://freeimage.kr/bbs/board.php?bo_table=iphone&wr_id=16
 

0.

아이폰의 푸시 서비스는 애플에서 제공하는 APNS(Apple Push Network Server)를 이용한다. 개별 아이폰 기기를 식별하는 udid 와 앱스토어의 개발자 계정만 갖고 있으면 푸시 서비스가 가능한 것. 왜 그랬는지는 도무지 모르겠지만 얼마전까지만 해도 안드로이드는 그러한 서비스를 갖고 있지 않았다. 따라서 무진장 귀찮게 커스텀 푸시 서비스를 구축하거나, 엄청난 배터리 소모와 트래픽을 요구하는 polling 방식을 사용할 수 밖에 없었던 것. 구글이 뒤늦게나마 정신 차려서 만든 것이 C2DM. 구글이 개발자에게 제공하는 푸시 네트웍 서버 되시겠다.

1.

안드로이드 내부에서 설정하는 부분은 그렇게 어렵지도 않거니와, 참고자료가 무진장 많다. 따라서 설명은 생략.
나보다 훨씬 더 잘 설명해주실 분들의 링크로 대신한다.

http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110087032264
http://eddykudo.com/91
http://code.google.com/android/c2dm/


2.

안드로이드 쪽의 개발은 전혀 문제가 없었는데, 전혀 문제 될 거라 생각하지 못했던 서버 쪽에서 문제가 발생했다.
구글이 제공하는 친절한 예제는 죄다 자바 서블릿 기반이라 PHP 로 만들어야 하는 내게는 쓸데 없는(그리고 머리 아픈) 자바 코드일 뿐이었다.
뭐 어쨌든 그 덕에 한동안 쓸 일 없었던 curl 을 징그럽게 공부했다. (그러나 늘 그렇듯 풀고보니 사소한 실수였음)

 
 
$ch = curl_init();   
   
curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");   
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);   
   
$data = array('accountType' => 'HOSTED_OR_GOOGLE',   
'Email' => '아이디',   
'Passwd' => '비번',   
'source'=>'test-1.0',   
'service'=>'ac2dm');   
    
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);   
curl_setopt($ch, CURLOPT_POST, true);   
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);   
 
$result = curl_exec($ch); 
$auth = substr(strstr($result, "Auth="), 5);  
$auth = substr($auth, 0, strlen($auth)-1); 
 
curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send"); 
 
$data = "registration_id=등록아이디"."&collapse_key=1"."&data.msg=메세지"; 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
 
$headers = array( 
    "Content-Type: application/x-www-form-urlencoded", 
    "Content-Length: ".strlen($data), 
    "Authorization: GoogleLogin auth=$auth" 
); 
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);  
 
$result = curl_exec($ch); 
echo $result."\n"; 
 
curl_close($ch); 
 
 


정리 전혀 안된 명백한 테스트코드.
php 의 curl 모듈(일반적으로 기본설치)을 이용해 구글 ClientLogin 의 Authentication 을 획득하고, 그 복잡다단한 키를 헤더에 포함하여 c2dm 서버에 날리면 된다.
아아주 쉽다.


3.

사실 저 부분에서 포인트는 

 
$auth = substr($auth, 0, strlen($auth)-1); 


달랑 요 한 줄이다. 
보는 바와 같이 끝에 붙은 글자 하나 날리는 간단한 구문.
요 한 줄 때문에 한나절은 꼬박이 삽질했다.
단일 헤더 프로퍼티에는 절대, 무조건, 반드시! 개행문자가 삽입되면 안된다.
그런데 Google ClientLogin 으로 요청하면 SID, AUTH 등의 개별 키들을 개행문자로 구분해버리니 쉴 새 없이 Unauthorized 메세지가 뜬 것이다.


4.

비전공자가 보면 귀신 시나락까먹는 소리고, 이 블로그 방문객의 대다수가 비전공자이기 때문에 요런 글 웬만하면 안 쓰자-라는 주의였는데.
일하면서든, 혼자 뚜닥거리면서든 이렇게 작은 경험 올려주시는 많은 개발자 분들 덕택에 쉽게쉽게 갈 때가 많아
나름 보은의 차원에서 짧게 두드려봤다.

덧,
혹 C2DM 시도하다 해결되지 않는 문제가 있다면 댓글 남겨주시길.
해결은 못 해드려도, 같이 고민은 해드릴게요. ㅋ