기본 콘텐츠로 건너뛰기

go로 android notification server를 만들었다.

내가 처한 갑갑한 상황은 이런 것이었다.

1. Android 용 notification server + client 를 구현해야한다.
2. 서비스 서버는 내가 손을 댈수 없지만 windows+asp 기반으로 되어있다.
3. 내 컴퓨터는 OS X다 (....)
4. 소스가 노출되는 형태의 결과물은 안된다(script류 X)
5. 서버 구동을 위해 별도의 프로그램을 설치할 수 없다 (java 안됨)
6. exe 파일을 만들어야한다. 그것도 OS X에서
7. C/C++로?
8. 테스트 용으로 디플로이도 해야할 것 같다.

그래서 떠올린 것이 go.
유지보수도 겸해서 천치도 읽을 수 있게 짜고 싶었다.

go-gcm package를 일단 써서 후지고 빠르게 만들자.
https://gist.github.com/acidsound/5121536#file-tinygcmserver-go


// +build !appengine
package main
 
/*
* Usage: ./TinyGCMServer.go <API_KEY> <Server URL(:port)>
* Test: curl -d "<NOTIFICATION MESSAGE>" http://serverURL/sendMessage?target=<REGISTRATION_ID>
*/
import (
"fmt"
"github.com/googollee/go-gcm"
"io/ioutil"
"net/http"
"os"
)
 
var API_KEY string
 
func main() {
serverURL := "localhost:8000"
if len(os.Args) > 1 {
API_KEY = os.Args[1]
if len(os.Args) > 2 {
serverURL = os.Args[2]
}
http.HandleFunc("/sendMessage", sendMessageHandler)
fmt.Println("Notification server initialized.. : ", serverURL)
fmt.Println("API Key : ", API_KEY)
http.ListenAndServe(serverURL, nil)
}
}
 
func sendMessageHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
body, _ := ioutil.ReadAll(r.Body)
target := r.FormValue("target")
fmt.Fprintln(w, "target :", target)
fmt.Fprintln(w, "body :", string(body))
sendGCMNotification(target, string(body))
}
}
 
func sendGCMNotification(target string, message string) {
// API Key
client := gcm.New(API_KEY)
 
// client ID
load := gcm.NewMessage(target)
// load.AddRecipient("abc")
load.SetPayload("data", message)
// load.CollapseKey = "registerCar"
load.DelayWhileIdle = true
load.TimeToLive = 10
 
resp, err := client.Send(load)
 
fmt.Printf("id: %+v\n", resp)
fmt.Println("err:", err)
fmt.Println("err index:", resp.ErrorIndexes())
fmt.Println("reg index:", resp.RefreshIndexes())
}


코드를 다 짜고 난 다음 실행해보고 생각보다 잘돌아가서 만족
말로 만들었던 크로스 컴파일에 도전.

먼저 
$ cd /usr/local/go/src/
$ sudo GOOS=windows GOARCH=386 CGO_ENABLED=0 ./make.bash --no-clean

컴파일 돌렸다.
만일 리눅스 바이너리를 만들려면 
$ sudo GOOS=linux GOARCH=386 CGO_ENABLED=0 ./make.bash --no-clean

뭐 이러면 될듯.
컴파일이 끝나면
---
Installed Go for windows/386 in /usr/local/go
Installed commands in /usr/local/go/bin
$

요렇게 떨어질 것이다.
다음은 exe 파일을 만들어보자.

$ GOOS=windows GOARCH=386 go build -o appname.exe appname.go

이럴려고 컴파일 한거니까.
오오 진정 exe 파일을 제가 만들었단 말입니까!

윈도우에서도 잘 돌아갈 것이다.
단 curl 류를 사용한다면 cmd 에서 codepage를 주의할 것.

댓글

  1. http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
    GCM 전반적인 개발에 대한 내용. 그림이 있어서 일단 추가

    답글삭제
  2. POST대신 GET으로 변경하고 좀 더 단순화한 소스를 gist에 올렸습니다.
    https://gist.github.com/acidsound/5424720

    답글삭제

댓글 쓰기

이 블로그의 인기 게시물

LG G Pro 2 Custom Rom +Rooting 기록

선 루팅 https://forum.xda-developers.com/lg-g3/general/guide-root-lg-firmwares-kitkat-lollipop-t3056951 1.2버전 스크립트 모드로. echo Looking for LG serial port.. echo. adb.exe wait-for-device 여기에서 정체 상태여서 강제로 adb kill-server 했더니 알아서 재부팅하심. 폰에선 "펌웨어 업데이트"화면이 나오고 Phone found at COM5! Rooting phone.. If you don't see the SuperSu installer script runs within about a minute, then the root failed. Author : blog.lvu.kr SPECIAL COMMAND : ENTER, LEAVE ## 이런 상황이 됨. #이 느린 속도로 하나씩 증가하고 있음. 한 시간 기다려도 성과없음. 뭐 몇번해봐도 안되고 결국 불안하긴 하지만 kingroot.net  로 설치 롤리팝이니까  https://drive.google.com/file/d/0B4kfGU1z_PClQ3AyM2lKOGR1S3M/view  이걸 받아서 압축 풀기. d838recovery.bat 만 있어서 당황스럽긴한데 실행하고 1번 하니까 리커버리 모드 진입까진 잘 되는 듯. adb sideload 라는게 있어서 해봄. Advance에서 adb sideload 선택하고 USB연결한 PC에서 adb sideload RR-N-v5.8.5-20171010-d838-Final.zip 하니까 착착 잘 진행됨. 이제 흉측한 U+LTE 가 없어짐. ㅇㅋ 군더더기 없고 깔끔한데 남은 건 gapps 를 설치해야함. http://opengapps.org/  를 권해줘서 갔는데 지옥 느림. ARM + 7.1 + stock 이 기본이...

MQTT 접속해제 - LWT(Last will and testament)

통신에서 중요하지만 구현이 까다로운 문제로 "상대방이 예상치 못한 상황으로 인하여 접속이 끊어졌을때"의 처리가 있다. 이것이 까다로운 이유는 상대방이 의도적으로 접속을 종료한 경우는 접속 종료 직전에 자신의 종료 여부를 알리고 나갈 수 있지만 프로그램 오류/네트웍 연결 강제 종료와 같은 의도치 않은 상황에선 자신의 종료를 알릴 수 있는 방법 자체가 없기 때문이다. 그래서 전통적 방식으로는 자신의 생존 여부를 계속 ping을 통해 서버가 물어보고 timeout 시간안에 pong이 안올 경우 서버에서 접속 종료를 인식하는 번거로운 방식을 취하는데 MQTT의 경우 subscribe 시점에서 자신이 접속 종료가 되었을 때 특정 topic으로 지정한 메시지를 보내도록 미리 설정할 수 있다. 이를 LWT(Last will and testament) 라고 한다. 선언을 먼저하고 브로커가 처리하게 하는 방식인 것이다. Last Will And Testament 라는 말 자체도 흥미롭다. 법률용어인데  http://www.investopedia.com/terms/l/last-will-and-testament.asp 대략 내가 죽으면 뒷산 xx평은 작은 아들에게 물려주고 어쩌고 하는 상속 문서 같은 내용이다. 즉, 내가 죽었을(연결이 끊어졌을) 때에 변호사(MQTT Broker - ex. mosquitto/mosca/rabbitMQ등)로 하여금 나의 유언(메시지)를 상속자(해당 토픽에 가입한 subscriber)에게 전달한다라는 의미가 된다. MQTT Client 가 있다면 한번 실습해보자. 여러가지가 있겠지만 다른 글에서처럼  https://www.npmjs.com/package/mqtt  을 사용하도록 한다. npm install mqtt --save 로 설치해도 되고 내 경우는 자주 사용하는 편이어서 npm install -g mqtt 로 전역설치를 했다. 호스트는 무료 제공하고 있는 test.mosquitto.o...

OS X 터미널에서 tmux 사용시 pane 크기 조절

http://superuser.com/a/660072  글 참조. OS X 에서 tmux 사용시 나눠놓은 pane 크기 조정할 때 원래는 ctrl+b, ctrl+↑←→↓ 로 사이즈를 조정하는데 기본 터미널 키 입력이 조금 문제가 있다. 키 매핑을 다시 하자 Preferences(cmd+,) > Profile >  변경하고자 하는 Theme 선택 > Keyboards 로 들어가서 \033[1;5A \033[1;5B \033[1;5C \033[1;5D 를 순서대로 ↑↓→←순으로 매핑이 되도록 하면 된다. +를 누르고 Key에 해당 화살표키와 Modifier에 ctrl 선택 한 후 <esc>, [, 1, ;, 5 까지 한키 한키 입력 후 A,B,C,D를 써준다. 잘못 입력했을 땐 당황하지 말고 Delete on character 버튼을 눌러 수정하도록 하자. 그리고 다시 tmux에서 ctrl+b, ctrl+↑←→↓로 사이즈를 조절해보자. 잘 된다.