제임스딘딘의
Tech & Life

개발자의 기록 노트/Android

[안드로이드] Push Notification 구현

제임스-딘딘 2011. 6. 22. 17:04

[안드로이드] Push Notification 구현


안드로이드에서 Push notification을 구현하기 위한 방법으로 XMPP를 이용하는 방법과 MQTT를 이용하는 방법이 있다. 
여기서는 MQTT를 이용하여 C2DM을 지원하지 않는 안드로이드 2.1이하 버전에서 PUSH notification을 지원하기 위한 방법에 대해 설명한다.

안드로이드 앱에서 Push notification을 지원하기 위한 방안은 3가지정도의 방안이 있다.

폴링

이게 진정 push일까?? 어쨌든 단말에서 주기적으로 서버에 가져갈 메세지가 있는지 확인하여 push event를 수신할 수 있다.

  장점 : 구현이 쉽고 비용도 안든다.
  단정 : 실시간이 아니지 않은가... 게다가 이는 배터리소모까지 발생시킨다.. 끔찍하다. 이에 대한 정보는 이 링크를 참조하자. 



SMS

  안드로이드는 SMS message의 가로채기가 가능하다. 서버에서 특별한 SMS를 단말에 날리면 앱에서는 모든 SMS 메세지를 가로채서 서버에서 날린것인지 확인하고 Popup Message를 띄울 수 있을것이다.

  장점 : 구현이 쉽다. 완전한 실시간이 보장된다. 알려진 솔루션도 있다. Ericsson lab의 자료를 참조하라 -> https://labs.ericsson.com/apis/mobile-java-push/
  단점 : SMS 발송 시, 건당 비용이 발생한다.


끊김없는 TCP/IP(persistent TCP/IP)

폰과 서버가 TCP/IP 연결을 유지한다. 그리고 주기적으로 keepalive메세지를 날린다. 서버는 이 연결을 통해 필요할경우 메세지를 보낸다.

  장점 : 완전한 실시간이 보장된다.
  단점 : 신뢰성을 보장하는 구현이 아주 까다롭다. 폰과 서버쪽 모두 구현하려면 이야기가 복잡해진다. 또 안드로이드는 low memory등의 상황에서 서비스가 종료될 수도 있다. 그러면 동작을 안할것이다. 또한 단말이 sleep에 들어가지 않아야 하므로 유저들은 배터리문제로 불만을 제기하거나, 소리없이 당신의 앱을 삭제해버릴 수 있다.


1, 2의 방법은 중대한 단점이 있다. 3번째는 가능하기는 하다. 하지만 역시 개운치는 않다.

구글링을 통해서 몇몇 개발자들의 TCP/IP방식의 몇가지 좋은 시도를 찾았다.

Josh guilfoyle은 AlarmManager에 기반하여  오랬동안 살아있는 connection을 어떻게 만들것인가에 대해 언급했다.
그는 백그라운드에서 동작하면서 그 연결을 만들어내는 멋진 샘플코드도 제공하였다. 


Dave Rea는 Deacon project를 최근에 시작했다. Meteor server상에서 comet technology를 사용하여 안드로이드에서 push notification을 지원하는 3rd party library를 개발할 예정이다. 아주 초기 단계이다.  


지금은 페이지가 삭제되어 더이상 접근이 되지 않는다.

Dale Lane는 IBM에서 개발한 MQTT protocol로 android에서 push notification을 지원하는것과 관련한 많은 자료를 만들었으며 아주 훌룡한 샘플코드도 제공한다. http://dalelane.co.uk/blog/?p=938

위의 훌룡한 시도들을 기반으로 예제를 만들었다. 이는 Josh Guilfoyle의 TestKeepAlive project 와 Dale Lane의 MQTT를 이용한 것이다.

TestKeepAlive project의 문제점은 raw TCP connection을 만든다는 것이다. 이는 push를 관리하는 서버를 별도로 작성해야 한다는것을 의미한다. MQTT를 이용한 예제의 경우 서버작업을 위해 IBM의 MQTT broker를 이용한다. 

mqtt는 publish/subscribe messaging protocol로 가볍게 설계 되었다. 가볍게 설계 되었다는 것은 '저전력 소모'를 지원한다는 것이다. 이는 끊김없는 TCP/IP connection을 고려해야 하는 모바일환경에서 가장 이상적인 해결책이다. 다만 MQTT의 단점은 개인의 프라이버시 보장이 약하다는 것 등 몇가지 단점이 있기는 하다.

KeepAliveService와 raw TCP/IP connection을 MQTT connection으로 변경하는 것이 아이디어의 핵심이다.

Architecture

예제에서는 서버에서 PHP를 사용하였다. 이는 Simple Asynchronous Messaging library(http://project-sam.awardspace.com/)를 사용하였다.




wmqtt.tar 는 IBM에서 제공하는 MQTT protocol의 간단한 drop-in implementation이다.  http://www-01.ibm.com/support/docview.wss?rs=171&uid=swg24006006에서 다운로드 가능하다. 

Really Small Message Broker(RSMB)는 간단한 MQTT broker로 마찬가지로 IBM에서 제공한다. http://www.alphaworks.ibm.com/tech/rsmb에서 다운가능하다. 1833포트가 디폴트로 동작한다. 위 아키텍쳐에서 서버로부터 메세지를 받아서 단말에 전송하는 역할을 한다. RSMB는 Mosquitto server(http://mosquitto.atchoo.org/)로 변경이 가능하다.
SAM은 MQTT와 다른 요소들을 모아놓은 PHP library이다. http://pecl.php.net/package/sam/download/0.2.0에서 다운가능하다.

send_mqtt.php는 POST를 통해 메세지를 받아서 SAM을 이용하여 broker에 메세지를 전달하는 역할을 한다.

Sample code and Demo

이 예제는 TextView하나와 두개의 Button이 있다. 폰에 설치 후 서비스를 시작한 후 
http://tokudu.com/demo/android-push/  에 가서 deviceID를 입력하고 메세지를 입력하라. 그러고 난 후 "Send Push Message"를 누르면 폰에서 메세지를 받을 것이다. 
MQTT는 사실 안드로이드에서 Push를 지원하기 위한 최적의 방법은 아니다. 하지만 잘 동작한다. MQTT의 가장 취약한 점은 broker가 동작하는 IP와 PORT정보를 누군가 알아낸다면 모든 Push message들을 가로챌수 있다는 것이다. 따라서 그런 정보를 encrypt하는것은 좋은 대안이 될것이다. 대안으로 당신만의 broker를 작성하여 MQTT에 인증을 추가하는것이 있을 수 있다.

이 예제는 더 테스트되어야 한다. 안정성은 보장못한다. 연결이 끊어지거나 예외상황들에 대한 처리가 더 개선되어야 한다.