어쩌다 보니 이메일 보내는 기능을 구현하게 됐습니다. 요즘 서비스 하나 만들려고 보면 이메일 보내기 기능은 거의 기본적인 기능이라 필수적으로 알아야 하는 부분이라고 볼 수 있습니다. 

이 포스트는 두 부분으로 되어 있습니다.

1. SMTP 서버 설정하는 부분
2. Node.js 에서 이메일 보내는 부분



사실 2번은 무지 쉬웠습니다. nodemailer 라는 훌륭한 패키지가 존재하기 때문이지요. 1번은 너무나 쉽고도 오래된 이야기인지 오히려 관련 문구를 찾기가 어려웠습니다. 

개발환경은 역시나 서버 사이드 이기 때문에 Ubuntu 12.10 버젼에서 테스트 했습니다.

1. Sendmail 을 설치해줍니다.

 $ sudo apt-get install sendmail



Postfix 를 요즘 많이 쓴다고 하는데, 귀찮아서 걍 편한 sendmail 을 설치해줬습니다. 처음 설치된 sendmail 은 오로지 Localhost Only 입니다. 사실 이게 편하긴 합니다만, 제 주요 개발 환경은 OSX 이고, 원격에 서버가 설치되어 있는 관계로 sendmail 을 원격에서 접속해서 메일을 보낼 수 있게 설정해 줄 필요가 있습니다.

2. 원격에서 접속할 수 있게 sendmail.mc 를 바꾸어 줍니다.
/etc/mail/sendmail.mc 를 열고 다음줄을 찾아서 바꾸어줍니다.

DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp, Addr=127.0.0.1')dnl 


인 부분을

DAEMON_OPTIONS(`Family=inet,  Name=MTA-v4, Port=smtp, Addr=0.0.0.0')dnl


로 바꾸어 줍니다.

아무데서나 접속가능하게 바꾸어 준것입니다. 자 이제 설정파일을 생성해줍니다.

$ sudo bash -c "cd /etc/bash && m4 sendmail.mc > sendmail.cf" 
$ sudo /etc/init.d/sendmail restart



3. 접속 테스트 시작 
원격에서 접속하는 것을 가정으로 하고 sendmail 이 설치된 서버는 편의상 'crazia.super.com' 이라고 하지요. 

$ telnet crazia.super.com 25 

Connected to crazia.super.com
Escape character is '^]'.
220 teemo ESMTP Sendmail 8.14.4/8.14.4/Debian-2ubuntu2; Mon, 18 Mar 2013 11:54:40 +0900; (No UCE/UBE) logging access from: [10.10.10.10](FAIL)-[10.10.10.10]
HELO teemo
250 teemo Hello [10.10.10.10], pleased to meet you
MAIL FROM: crazia@super.com
250 2.1.0 crazia@super.com... Sender ok
RCPT crazia@gmail.com
501 5.5.2 Syntax error in parameters scanning "crazia@gmail.com"
RCPT to: crazia@gmail.com
550 5.7.1 crazia@gmail.com... Relaying denied. IP name lookup failed [10.10.10.10]



붉은색 부분은 제가 실제로 입력해 주는 부분입니다. 

헛 이런 낭패할 때가 !! Relay 가 안된다는 것이군요. 

4. access 에 개발 머신의 아이피를 써주기
/etc/mail/access 파일을 열어서 적당한 곳에

Connect:10.10.10.10                        RELAY



라고 추가해 줍니다. 그리고 3번 테스트를 다시 진행하고  

$ telnet crazia.super.com 25 

Connected to crazia.super.com
Escape character is '^]'.
220 teemo ESMTP Sendmail 8.14.4/8.14.4/Debian-2ubuntu2; Mon, 18 Mar 2013 11:54:40 +0900; (No UCE/UBE) logging access from: [10.10.10.10](FAIL)-[10.10.10.10]
HELO teemo
250 teemo Hello [10.10.10.10], pleased to meet you
MAIL FROM: crazia@super.com
250 2.1.0 crazia@super.com... Sender ok
RCPT TO: crazia@gmail.com
250 2.1.5 crazia@gmail.com... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: Main from me
It's me !!
.
250 2.0.0 r2I3MdYY028635 Message accepted for delivery
^C
quit

 
이제 정상적으로 메일이 보내지는 것 까지 테스트 되었습니다. 이제 node.js 로 이메일 보내는 방법에 대해서 알아보겠습니다. 

1. nodemailer package 설치하기 
먼저 테스트를 만들 디렉토리를 한개 만들어 주는 것이 좋겠습니다. 

$ mkdir mail-test
$ cd mail-test



그리고 npm 으로 가볍게 인스톨 해줍니다. 

$ npm install nodemailer



2. 실제로 보내는 테스트 코드 작성하기


위 내용을 자신의 상황에 맞게 변경하고 접속 host , 이메일 아이디 (제 아이디 쓰시면 아니되옵니다 ㅎㅎ) 저장합니다. 

3. 실행해보기

$ node mail-test.js



어떻습니까? 참 쉽죠? 

 
node.js 프로그래밍을 할 때, exception 이 발생하면 , 쉴새 없이 Ctrl+C , 화살표 위 (이러면 전에 실행했던 명령줄이 표시됩니다)를 반복적으로 누르는 것을 막아주기 위해서 설치하는 프로그램인 nodemon 이 Ubuntu 계열에서 오동작을 합니다. (하위 디렉토리에서 변경된 것을 잡아채지 못하더군요) 

소스를 뒤져보니 파일의 변경유무를 알아보던 fs.watch 를 이제 안쓰기 때문이라고 하는데요. 그래서 소스 변경 유무를 다음과 같은 명령 형식으로 알아봅니다. (사실 다음 소스는 동작하는 여부인지 골라내는데 사용하는 코드입니다) 

find -L /dev/null -type f -mtime -1s -print

위 명령이  데비안 계열하고 BSD 계열이 다르게 동작하는데 실은 저 명령은 BSD 계열을 기본으로 해서 만들어 진 것입니다. (개발자가 맥빠였던 것입니다!!) 

그래서 우분투에서 개발하시는 분들은 귀찮으시더라도 패치되기 전까지 supervisor 를 사용하시면 됩니다. 사용법은 비슷합니다.  

$ npm install supervisor -g
$ supervisor app.js



편리한 node.js 코딩 되세요. 
 
 node.js 를 이용해서 개발한지가 몇개월 지났습니다. 그동안 언어 배우느라 (자바스크립트를 할 줄 몰랐음) - 사실 언어 자체는 어려울게 하나도 없더군요. - 개발 환경에 익숙해 져야 해서 좀 더 나에게 맞는 편리한 환경을 만들 여력이 없었으나 이제는 어느정도 익숙해 져서 개발 환경쪽에 신경이 쓰이더군요. (사실은 웹일을 하기 싫어서 딴 짓을 하고 있..)

제가 설명드리는 기준은 OSX 입니다. (우분투를 사랑하지만 제 개발 환경은 OSX 라..)

avascript 개발하는데 있어서는 완전 필수입니다. 문법 체크까지 해서 이상한 거는 빨간 밑줄을 그어주더군요. (빨간펜 선생님?!!) 

설치법 입니다. 

$ svn checkout http://js2-mode.googlecode.com/svn/trunk/ js2-mode
$ cd js2-mode
$ emacs --batch -f batch-byte-compile js2-mode.el
$ cp js2-mode.elc ~/.emacs.d/


이러면 설치 끝입니다. 일단 설치만 하고 나중에 설정을 하기로 합니다. 

yasnippet 

TextMate 의 함수 템플릿 기능을 보고 만든 Minor 모드 입니다. 이런 것이 이맥스의 가장 큰 장점입니다. 필요하면 만들면 된다!! 
이것의 사용법은 쉽습니다. 예를 들면 자바스크립트 코딩할 때 함수 선언할 일이 필요하다면 

fun 입력하고 TAB 을 누르면 함수의 템플릿이 자동으로 생성됩니다. 

/**  */
function my_function( args ){
  
}


이런식으로 그러면 함수 설명과 my_function 과 args 부분을 적어주기만 하면 됩니다. 
https://github.com/capitaomorte/yasnippet 여기에 잘 정리가 되어 있습니다. 설치법도 있지만 퍼 와서 보자면 

$ cd ~/.emacs.d/plugins
$ git clone https://github.com/capitaomorte/yasnippet



.emacs 파일의 한 구석에 

(add-to-list 'load-path
              "~/.emacs.d/plugins/yasnippet")
(require 'yasnippet)
;; (yas-global-mode 1)    


(yas-global-mode 1) 는 필요할 때만 쓰게 일단은 커멘트 처리 해 둡니다. 


js2-mode 인덴테이션(indentation) 수정 

js2-mode 를 쓰거나 아니면 이클립스에서 개발을 하거나, 가장 문제가 되는 것이 바로 이 인덴테이션이더군요. 정말 그지 같은 인덴테이션 아닌가요? 탭 (tab) 한번 누르면 화면의 1/3 정도 지나쳐서 커서가 위치하는 것을 보면 한숨이 나오더군요. 그런데 역시 세상에는 같은 고민을 가지고 있으면 해결할려고 하는 사람도 있는 법입니다. 


바로 여기 입니다. 여기에 보면 수정하는 방법이 잘 정리가 되어 있습니다. js2-mode 는 이미 설치를 했기 때문에 중간에서 설명하고 있는 에스프레소(espresso) 를 설치해줍니다. (java 가 커피라 그런지 에스프레소 등등의 네이밍들이 요즘 눈에 띄는군요 ㅎㅎ) 


여기서 받아주면 됩니다. 이 모드를 설치해 주는 이유는 인덴테이션이 좋기 때문이라고 글쓴이가 설명하고 있더군요. 참고로 저는 저 파일을 ~/.emacs.d/ 밑에 복사해 뒀습니다. 역시 설치만 하고 설정은 나중에 하는 걸로 합니다. 여기까지 설치가 됐으면 이제 글쓴이가 만든 함수 부분이 기니까 한꺼번에 설정하겠습니다. 

~/.emacs.d/ 에 파일 한개를 만들어 줍니다. (제 경우에는 cr-js.el 이였습니다) 
그러면 cr-js.el 이라고 가정을 하고 다음 과 같은 내용을 추가 해 줍니다. 그리고 다음과 같이 파일은 만들어 줍니다. 



그리고 .emacs 파일에 

(require 'cr-js)


한줄만 추가해 주면 됩니다. 
내친김에 다른 것도 손을 좀 볼까요? 
node.js 에서 웹을 개발할 때 쓰는 view 엔진이 여러개가 있습니다. (정확히는 express) 기본적으로 jade 가 쓰이고요. 디자이너들과 공동 작업을 할 때는 ejs 가 많이 쓰인다고 합니다. ejs 를 쓸때 마땅한 모드가 없더군요. 그런데 ruby on rails 에서 사용하는 rhtml 이 문법이 거의 비슷하더군요. 그래서 rhtml-mode 를 설치해 주기로 합니다. 


요게 다른 모드랑 연계해서 동작하지 않고 독자적으로 rhtml 을 처리하더군요. 맘에 들어서 설치해줬습니다. 

$ cd ~/.emacs.d
$ git clone git://github.com/eschulte/rhtml.git 


그리고 .emacs 에 

(add-to-list 'load-path "~/.emacs.d/rhtml")
(require 'rhtml-mode)

(add-to-list 'auto-mode-alist '("\\.ejs$" . rhtml-mode))
(add-hook 'rhtml-mode-hook
          (lambda ()
            (yas-global-mode 1)))


이렇게 추가해 주면 됩니다. 한가지 이상한 점이 있지요? rhtml 도 yas 모드가 있는지 궁금하실 것입니다. (설정에 보면 있는 것처럼 하는데) 그래서 설치해 주기로 합니다. 


rails 용 snippet 을 모아둔 것들입니다. 당장은 rails 개발을 안할꺼기 때문에 rhtml 용만 떼어 오기로 합니다. 

$ cd ~/
$ mkdir temp
$ cd temp
$ git clone git://github.com/eschulte/yasnippets-rails.git
$ cd yasnippet-rails 
$ cd rails-snippets
$ cp -r rhtml-mode ~/.emacs.d/plugins/yasnippet/snippets/


이렇게 해주면 snippet 이 설치가 됩니다. 이제 편하게 코딩을 하시면 됩니다. 

ps.

js2-mode 용 snippet 도 설치를 하셨다면 node.js 에서 자주 쓰이는 prototype method 선언하는 템플릿을 만들어 두면 편합니다. 제가 만들어 쓰는 것을 공개합니다. 

# -*- mode: snippet -*-
# name: protf
# contributor: Wolfgang crazia <crazia@gmail.com>
# --
/** $1 */
${2:my_class}.prototype.${3:method_name} = function ( ${4:args} ){
    $0
}


이 파일 이름을 (확장자 없이) protf 로 만들고 

~/.emacs.d/plugins/yasnippet/snippets/js2-mode/protf 


로 저장하면 나중에 자바스크립트 파일 편집중에 protf 라고 입력하고 탭 (tab)키를 누르시면 자동으로 템플릿이 완성됩니다. 

ClojureScript 라고 들어 보셨는가요? 자바 스크립트 (Javascript) 는 대단히 편리한 언어이고 렉시칼 스코프 (Lexical Scope)를 지원해서 Anonymous Function 이나 Closure 를 지원하는 등, 고급 추상적인 언어가 지녀야할 몇가지 장점을 지니고 있습니다. 또한 문법도 쉽고 그래서 빠르게 전파되고 있습니다. 게다가 V8 엔진을 쓰는 Node.js 등 이제는 속도면에서도 자바(Java)에 필적하고 있습니다. (예전 제 포스트 참조) 

그러나 자바스크립트는 또한 약점이 존재합니다. 자바스크립트 지지자들도 여러번 지적하는 사항이라고 하는데요 (사실 저는 잘 모르겠습니다 -ㅅ- ). 지나치게 단순하고 어딘가 허술하며, 확장시키기 좋지 않으며 어떤 기능을 구현하기 위해서 불편하게 추가해야 하는 사항이 많다는 것입니다. 그런 이유로 커피스크립트 (CoffeeScript) 같은 것이 나와서 자바스크립트의 그러한 문제점들을 보완하고 있다는 것입니다. 

그래서 숨어있던 리습(Lisp)의 추종자들이 구글이 제공하는 Google Closure Compiler 의 힘을 바탕으로 해서 강력한 어둠의 Lispy Magic 을 이용해서 커피 스크립트 같은 것을 만들어 냈습니다. 그것이 바로 ClojureScript 입니다. 

예전에 폴 그레이엄이 말하길 '자신이 개발해야 하는 언어로 가장 생산성 있게 개발하고 싶다면, 그 언어를 이용해서 Lisp 해석기를 만들고 그 리습으로 코딩을 하고 나중에 원래 언어로 컴파일 하라.' 라는 이야기를 한 적이 있습니다. 바로 그렇게 만들어 버린 것입니다. 개발자들은 ClojureScript 로 개발을 하고 Google Closure Compiler 로 컴파일을 하면 자바스크립트 파일이 튀어 나옵니다. 이 파일을 이용해서 Client Side 의 작업과 심지어는 Server Side (Node.jsJavascript 로도 바꾸어 줍니다) 작업까지도 일원화 할 수가 있습니다. 

이름에서도 유추할 수 있듯이 사용하고 있는 Lisp 의 방언 (dialect) 은 바로 Clojure 입니다. 

개요만 찾아서 보시고 바로 튜토리얼로 넘어가면 좋을 것 같습니다. 

OSX 에서 GNU Emacs 를 사용중입니다. 귀찮고도 짜증나는 것중의 한가지가 왠만한 것들에 PATH 가 전혀 안 잡혀 있다는 것입니다. 심지어 $HOME/.bash_profile 에 내용을 넣어준다고 해도 Emacs 는 그 Path 의 영향을 받지 않더군요. 현재 Emacs 가 가지고 있는 PATH 정보를 확인하고자 한다면 

M-x shell 


로 들어가서 Prompt 가 뜨면 

bash-3.2$ env | grep PATH
EMACSPATH=/Applications/Emacs.app/Contents/MacOS/bin
PATH=/usr/bin:/bin:/usr/sbin:/sbin


이렇게 빈약하게 걸려 있는 것 뿐입니다. 귀찮더라도 추가해 주고 싶은 PATH 가 있다면 .emacs 파일에 

(setenv "PATH"
  (concat
   "/usr/local/bin" ":"
   "/opt/local/bin" ":"
   (getenv "PATH")
  )
)


이렇게 추가해 주면 완성입니다. 더 추가해 주고 싶은 PATH 를 쭈욱 써주시면 됩니다. 

As programming environments grow in power, and languages become more abstract, the Lisp style of programming is gradually replacing the old plan-and-implement model. - Paul graham 



조금 의역을 하자면
(하드웨어 스펙들이 점점 좋아져서 언어별의 속도차이가 별로 티가 안나는) 프로그래밍 환경이 되어가면 갈 수록 , (프로그래밍) 언어들은 점점 더 추상적이 되어 가고 (조금 더 고수준의 언어가 되어 가고) 리습 스타일의 프로그래밍 방법들이 (Bottom-up 프로그래밍 스타일을 말하는 것 같습니다) 옛날 방식의 '계획을 세우고 구현을 하는' 모델을 점차적으로 대체할 것입니다. 

굳이 리습 스타일이라고 표현을 한 이유는 저 문구가 나온 책이 Ansi Common Lisp 이였기 때문이고요, 확실하게 예전의 워터폴 (Waterfall) 이라고 알려진 '요구사항 정의 - 분석 - 기획 - 설계 - 개발 - 테스트' 의 형식을 취하는 개발 방법론들은 점점 더 옛날 방식이 되어 가고 있습니다. 

게다가 하드웨어 스펙들이 점점 좋아지니, 자바나 노드제이에스(Node.js) 나 속도의 차를 일반 사용자는 잘 느끼지 못하는 단계에 이르다 보면 개발하기 빠른 언어로 프로젝트를 개발하는 것이 가장 좋겠지요. (빠른 하드웨어 시대에 가장 큰 병목은 개발자의 개발 속도 입니다) 

그런 의미에서 공감이 되는 글이라고 할 수 있습니다. (이 사람은 이걸 90년대 초반에 예견했네요 ㅎㅎ) 


 
Node.js express 를 이용해서 개발하다 보면 아쉬운 것이 한가지 있습니다. 본의 아니게 서버가 죽어버리는 일입니다. 물론 이런일이 발생하지 않게 에러 핸들링을 속된 말로 빡세게 해야 하지만 뭐 어떻게 알아서 그걸 다 하고 있습니까... (후다다다닥) 

만약 서버가 죽는다고 하더라도 우아하게 재시작 된다면 (gracefully restart 라는 표현을 쓰더군요) 추후에 비슷한 에러가 발생하지 않도록 조치를 취해줄 수가 있습니다.  

역시나 설치법은 무지 쉽습니다. npm 이 설치되어 있다고 가정한다면

$ sudo npm install forever -g 



이러면 설치되고, 원하는 스크립트 서버를 띄워주고 싶다면

$ forever start app.js


하면 데몬 형식으로 구동됩니다. 아! 로그도 봐야 하지요?

$ forever logs



하면 현재 띄워져 있는 스크립트랑 거기에 관한 로그에 대한 내역이 나옵니다.  내용을 보고 싶다면 , 예를 들어 한개의 스크립트 서버를 띄웠다고 가정한다면

$ forever logs 0



하면 tail 로 로그를 뒤지는 효과가 나옵니다. 자세한 설명은 원문을 찾아보시면 됩니다.

원문링크 : https://github.com/nodejitsu/forever 
푸시 기능 구현을 Node.js 에서 하기에는 너무 쉬운 관계로.. 안드로이드 쪽부터 보기로 하겠습니다. 
안드로이드는 실 기계에서 작업하지 않는 한 에뮬레이터에서 푸시 기능을 테스트 해 보기 위해서는 Google API 를 지원해야 합니다.

Android SDK Manager (Windows 메뉴에 보면 있습니다. OSX 기준) 를 실행시키고 화면을 보면 


Android 4.2 (API 17) 에 'Google APIs' 가 설치 되어 있어야 합니다. 만약 설치 안되어 있다면 체크박스에 체크 하고 설치해주시면 됩니다. 

Google API 가 설치되어 있는 형태의 '가상 기계'를 구동하셔야 푸시 이벤트 처리가 가능합니다. 

Android Virtual Device Manager 를 실행시킵니다. (역시 Windows 메뉴에 있습니다) 
그리고 새로 '가상 기계'를 설정해 주는데 OS 버젼 골라주는 곳? 그곳에서 Google API 라고 쓰여져 있는 버젼을 골라주면 됩니다. 


자 제것의 화면입니다. 같은 4.2 버젼이지만 Google API 를 쓰느냐 안 쓰느냐의 차이만 존재합니다. 

그리고 다시 Android SDK Manager 를 실행시켜줍니다.

 
위에 보이는 라이브러리를 설치해줍니다. 자 그러고 나면 

$SDK/extras/google/gcm/ 밑에 보면 프로젝트들이 설치되어 있습니다. 그중에서 samples 밑의 gcm-demo-client 를 주목해야 합니다.  (본인의 경우에는 /Users/crazia/work/android/sdk/extras/google/gcm/samples/gcm-demo-client 에 설치되어 있습니다. )

Eclipse 가 이미 구동되어 있을 테니 (안 그러면 SDK 메니져랑 가상 기계 매니져를 실행시킬 수 없었겠지요?) 위에 지정한 프로젝트를 Import 해옵니다. 

자 이제 안드로이드 쪽에서 해야 할일의 90% 는 끝이 난 셈입니다. 이제 키가 두개 필요합니다. 편의상 Project Key (SEND ID) 와 API Key 라고 부르겠습니다. 각각 클라이언트와 서버쪽에서 필요한 키입니다. 

https://code.google.com/apis/console 에 접속하셔서 


아직 등록이 안되어 있다면 'Create Project' 를 누르시면 프로젝트가 생성됩니다. 그리고 나면 URL 이 자동으로 변경이 되는데. 

https://code.google.com/apis/console/#project:4815162342

여기서 보이는 저 굵은 글자가 바로 Project Key 입니다. (SEND ID) 아이템을 얻었습니다!!

왼쪽에 탭을 보면 여러가지 메뉴가 있는데 그중에 

"Services." 탭을 선택합니다. 
"Google Cloud Messaging" 을 ON 으로 토글링 합니다. (켭니다) 


이제 구글 클라우드 메시지 서비스를 이용하기로 결정이 됐습니다. 
자 다시 왼쪽 탭을 보면 그중에서 

"API Access" 탭을 선택합니다. 
아래쪽에 보면 "Create New Server Key" 라는 버튼이 있습니다. 
보내고 싶은 IP 리스트에 대한 리스트를 작성해 주고 싶으면 작성하고 마땅히 할게 없으면 "Create" 버튼을 눌러줍니다. 



이제 중간에 나오는 화면에서 "API Key" 부분에 나와 있는 키를 따로 떼서 저장합니다. (Server Key) 아이템을 얻었습니다!!

중간 점검을 하자면 

1. Google API 를 지원할 수 있게 Virtual Device 를 생성하는 준비를 마쳤습니다. 
2. Extra/gcm 샘플 소스를 받아서 Eclipse 에서 쓸 수 있게 Import 했습니다. 
3. Sender ID 와 Server Key 로 사용할 수 있는 Project Number 와 API Key 를 받았습니다. 

여기까지 완수가 되었다면 이제 클라이언트 (Android) 쪽 코딩을 마무리 지어 봅니다. Eclipse 의 프로젝트에 포함된 파일중에서 CommonUtilities.java 파일을 열어줍니다. 

    /**

     * Base URL of the Demo Server (such as http://my_host:8080/gcm-demo)

     */

    static final String SERVER_URL = "http://192.168.0.36:3000";
    // node.js 서버가 기다리고 있는 주소와 포트를 적어 주는 것입니다. 


    /**

     * Google API project id registered to use GCM.

     */

    static final String SENDER_ID = "4815162342";
    // 위에서 얻은 Project Number 를 입력해 줍니다.

이로서 클라이언트 부분은 끝이 났습니다. 이제야 제일 핵심인 Node.js 에서의 푸시 기능 구현에 들어가겠습니다.

$ cd $PROJECT_DIRECTORY
npm install node-gcm --save

-- save 옵션을 package.json 에 해당 사항을 기입하라는 뜻입니다.  

app.js 를 열어서 다음과 같이 추가 해 줍니다. 

var main = require('main');

app.post('/register', main.regist);
app.get('/send', main.send_push);


main.js 파일을 하나 만들어서 열고 

exports.regist = function (req, res) {

console.log (req.param('regId'));
        // 원래는 DB 에 저장하는 부분이 있어야 할 것입니다. 받아서 디비에 저장하기       

res.end(); 


exports.send_push = function(req, res) {

var message = new gcm.Message();

var sender = new gcm.Sender('API Key 를 입력하는 곳입니다. ');

var registrationIds = [];


// Optional

message.addData('key1','message1');

message.addData('key2','message2');

message.collapseKey = 'demo';

message.delayWhileIdle = true;

message.timeToLive = 3;


// At least one required

registrationIds.push('이곳은 register 함수에서 받은 regId 를 입력하는 부분입니다.');
        // 만약 제대로 구현 됐다면 디비에서 읽어서 가져오겠지요?  

        

/**

 * Parameters: message-literal, registrationIds-array, No. of retries, callback-function

 */

sender.send(message, registrationIds, 4, function (err, result) {

    console.log(result);

});

// sender.sendNoRetry(message, registrationIds-array, function (err, result) {

//     console.log(result);

// }); // retry 없이 보내는 부분입니다. 보통은 이것을 더 많이 애용할 것 같습니다. 

}




너무 쉽게 끝났지요? 이게 node.js 의 힘이라고 볼 수 있습니다. 자신의 안드로이드 프로젝트에 기능을 추가하고 싶으시다면 참조 사이트를 참조하시면 됩니다. 

참조  사이트 

https://github.com/ToothlessGear/node-gcm : node.js 에 gcm 모듈 구현 
http://developer.android.com/google/gcm/gs.html : 구글의  gcm 모듈 구현하는 설명 페이지 (완전 중요!!)


 
GIT 은 소스 레파지토리 시스템인데 그 중에 특별히 '분산' 개념이 들어가 있습니다. 다른 레파지토리랑 (cvs, svn) 비교를 많이 하지만 '분산' 이라는 점에서 많은 차별점이 있습니다. 원래 태어날 때도 여타 소스 레파지토리에 '분산' 기능이 없기 때문에 태어났기도 합니다. 

조금 쉽게 이해를 하자면, GIT 은 기본적으로 제 Local 에 레파지토리를 가지고 있는 방식이라고 볼 수 있습니다. 즉 중앙 개념이 희박합니다. Local 에서 리비젼 관리가 완벽하게 이루어 집니다. Remote (원격) 개념은 공동 작업을 할 때 필요하다고 보면 될 것입니다. 결국 push / pull 은 원격에만 관여하는 것이고 나머지 기능들은 Local 에서 소스 관리하는 기능이라고 보시면 됩니다. (자질 구레한 것은 따지지 말기로 하죠 ㅎㅎ)

그렇다면 가장 헷갈리기도 하고 잘 쓰기가 어려운 merge / branch 개념을 git 에서는 필수적으로 사용할 줄 알아야 하는데 그 내용을 살펴보기로 하겠습니다. 

시나리오

1. 웹 사이트에서 일을 하는 중 
2. 새로운 스토리에 맞춰서 브랜치를 생성함
3. 위에서 생성한 브랜치에 무엇인가 작업을 하는중 

 이슈가 발생하고 핫픽스를 (hotfix) 해야 합니다. 이는 다음과 같은 절차로 할 수가 있습니다. 

1. 운영 브랜치로 바꾸고
2. 핫픽스를 추가할 브랜치를 생성합니다. 
3. 핫픽스가 테스트 됐다면,  핫픽스 를 머지(merge) 하고, 운영 브랜치로 밀어넣습니다. (push)
4. 원래 하던 작업으로 돌아가서 계속 일을 합니다. 


커밋이 세번 일어난 브랜치라고 가정합니다. 세번째 커밋을 master 가 가르키고 있는것에 주목합니다. 이 때 이슈가 발생했습니다. 이슈를 처리하기 위해서 브랜치를 만듭니다. 

$ git checkout -b iss53
Switched to a new branch "iss53"


iss53 으로 브랜치를 만듭니다. 이 명령은 실은 두가지 명령이 하나로 합쳐진 것입니다. 

$ git branch iss53
$ git checkout iss53


이렇게 하는 것이지만 귀찮으니 축약 버젼을 쓰기로 합니다. 



iss53 브랜치가 생성 됐기 때문에 2개의 브랜치가 공존하는 형태가 됩니다. C/C++ 언어의 포인터 개념과 비슷하군요 

그리고 그 브랜치에서 무엇인가 작업을 하고 커밋을 합니다. 가령 예를 들자면 

$ emacs index.html 
$ git commit -a -m 'added a new footer [issue 53]'


이런식으로 (원문의 vim 을 emacs 로 바꿨습니다.)



이제 이 와 같이 브랜치의 모습이 바꼈을 것입니다. 이제 작업한 내용을 합쳐야 합니다. 다시 master 브랜치로 바꾸어 줍니다. 

$ git checkout master
Switched to branch "master"

이제 핫픽스 해줘야 하는 경우 입니다. 브랜치를 만들고 수정을 가하고 commit 을 합니다. 

$ git checkout -b hotfix
Switched to a new branch "hotfix"
$ emacs index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix]: created 3a0874c: "fixed the broken email address"
1 files changed, 0 insertions(+), 1 deletions(-)





이 과정이 끝나면 위와 같은 형태로 브랜치들이 정리될 것입니다. 이제 머지(merge)를 해야 할 시간이 왔습니다. 

$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast forward
README |    1 -
1 files changed, 0 insertions(+), 1 deletions(-)


master 로 브랜치를 변경하고 합치는 것에 유의하셔야 합니다. 



master 와 hotfix 브랜치가 같은 곳을 지정하고 있습니다. 이제 브랜치(포인터) 하나를 삭제해 줍니다. 

$ git branch -d hotfix
Deleted branch hotfix (3a0874c).



그리고 다시 원래 하던 작업으로 돌아가서 작업을 계속 합니다. 

$ git checkout iss53
Switched to branch "iss53"
$ emacs index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53]: created ad82d7a: "finished the new footer [issue 53]"
1 files changed, 1 insertions(+), 0 deletions(-)




그러면 위와 같은 형태의 브랜치 모습이 될 것입니다. 

구체적으로 merge 부분을 자세하게 보는 것과 컨플릭트(conflict)를 해결하는 방법은 원문을 살펴 보세요 
무엇이든 지 간에 실제로 짜보기 전에는 공부가 됐다고 말할 수가 없을 것입니다. 그런 의미로 조금 복잡한 프로그램을 만들어 본다면, 거의 할 수 있는 최고의 공부가 될 것입니다. 거기다가 처음부터 차근 차근 만들어 볼 수 있다면? 

그런 의미에서 Nethack 이라는 게임을 클로져로 만들어 보는 것이 정말 괜찮은 공부가 될 수 있을 것입니다.  
저도 우연히 발견한 사이트 인데 정말 많은 공부가 되고 있습니다. 실전 Clojure 공부라고 볼 수 있습니다.

http://stevelosh.com/blog/  

1 부터 차례로 따라하시면 됩니다. 

+ Recent posts