본문 바로가기
Android

[Android GCM] 3. C언어로 GCM 메시지를 보내자!

by GGoris 2015. 7. 10.
반응형

3. C언어로 GCM 메시지를 보내자!


raspberryPI - Raspbian을 사용하였습니다.




서버측에 해당되는 코드입니다.


nodejs가 문제가 생기는 바람에

해결도 잘안되어 C로 간단하게 GCM Connection Server로

http POST를 보내어 해당 regstration Token의 device로 메시지를 전송합니다.




http://souptonuts.sourceforge.net/code/http_post.c.html

위 링크의 코드를 참조 하였습니다.




postc.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
 
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netdb.h>
#include <unistd.h>
 
#define SA      struct sockaddr
#define MAXLINE 4096
#define MAXSUB  500
 
 
#define LISTENQ         1024
 
extern int h_errno;
 
const char *apikey = "Type your Api Key";
 
ssize_t process_http(int sockfd, char *host, char *page, char *poststr)
{
    char sendline[MAXLINE + 1], recvline[MAXLINE + 1];
    ssize_t n;
    snprintf(sendline, MAXSUB,
            "POST %s HTTP/1.0\r\n"
            "Host: %s\r\n"
            "Content-type: application/json\r\n"
            "Authorization:key=%s\r\n"
            "Content-length: %d\r\n\r\n"
            "%s", page, host, apikey, strlen(poststr), poststr);
 
    printf("sendline : \n%s\n",sendline);
    write(sockfd, sendline, strlen(sendline));
    while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = '\0';
        printf("%s", recvline);
    }
    return n;
 
}
 
int main(void)
{
    int sockfd;
    struct sockaddr_in servaddr;
 
    char **pptr;
    char *hname = "gcm-http.googleapis.com";
    char *page = "/gcm/send";
    char *poststr = "{ \"notification\": {"
                           "\"title\": \"oh my title\","
                           "\"text\": \"What's wrong?\","
                           "\"icon\": \"@mipmap/ic_launcher\" },"
                       "\"to\" : \""
                            "Type your Regstration Token"
                       "\"}\r\n";
 
 
 
    char str[50];
    struct hostent *hptr;
    if ((hptr = gethostbyname(hname)) == NULL) {
        fprintf(stderr, " gethostbyname error for host: %s: %s",
                hname, hstrerror(h_errno));
        exit(1);
    }
    printf("hostname: %s\n", hptr->h_name);
    if (hptr->h_addrtype == AF_INET
            && (pptr = hptr->h_addr_list) != NULL) {
        printf("address: %s\n",
                inet_ntop(hptr->h_addrtype, *pptr, str,
                    sizeof(str)));
    } else {
        fprintf(stderr, "Error call inet_ntop \n");
    }
 
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(80);
    inet_pton(AF_INET, str, &servaddr.sin_addr);
 
    printf("connection...\n");
    connect(sockfd, (SA *) & servaddr, sizeof(servaddr));
    printf("process http...\n---------------------------\n%s\n----------------------\n",poststr);
    process_http(sockfd, hname, page, poststr);
    close(sockfd);
    exit(0);
 
}
 
 
cs


25라인에 자신의 Api Key를 적어 줍니다.

62라인에 이전단계의 앱에서 발급된 Registration Token을 적어 줍니다.






위 코드를 컴파일하고 실행!


하면!

앱에 푸시 알림이 뙇!



타이틀과 택스트의 내용은 위의 코드와 조금 다릅니다!

(코드 수정하기 전 캡쳐한 화면이라..)



서버쪽에

{"multicast_id":5999926841887427350,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1436530056921611%4f2946734f294673"}]}

success가 뙇!





만약 앱에서 unregst 버튼을 클릭한 상태

즉, Google Connection Server에서 등록을 해제한 상태일때

메시지를 보낸다면,

{"multicast_id":8938712565521443574,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"NotRegistered"}]}

failure가 옵니다!


failure메시지는 디바이스에서 앱이 삭제되어 메시지 수신이 불가한 경우에도 반환되므로

앱서버에 저장된 regstration Token값을 제거해주시면 됩니다.



앱에서 unregstration 후 다시 regstration을 한다면

토큰이 바뀐다는 사실에 유의 하시기 바랍니다!



끝!







앱에서 발급받은 토큰을 앱서버로 DB에 저장하고

앱서버는 위의 코드를 이용해 특정 이용자에게 메시지를 보낼 수 있습니다.


DB관련 부분은 모두들 잘 하시리리 믿습니다! :)






-------------------------------------------------------



[Android GCM] 0. GCM


[Android GCM] 1. 준비


[Android GCM] 2. GCM 안드로이드 앱!


[Android GCM] 3. C언어로 GCM 메시지를 보내자!





참고 내용


http, xmpp의 내용 구성을 위한 레퍼런스

https://developers.google.com/cloud-messaging/server-ref


제가 읽어본 안드로이드 관련 부분 링크입니다.

도입부

https://developers.google.com/cloud-messaging/android/start

App Server설명

https://developers.google.com/cloud-messaging/server

App Server에서의 http

https://developers.google.com/cloud-messaging/http

Client App에서의 등록에 관한 기본설명

https://developers.google.com/cloud-messaging/registration

안드로이드 Client App에서 해주어야 할 일

https://developers.google.com/cloud-messaging/android/client


반응형

'Android' 카테고리의 다른 글

[Button] 버튼 텍스트가 자동으로 대문자로 보일 때  (0) 2015.07.20
[Android GCM] 0. GCM  (0) 2015.07.11
[Android GCM] 2. GCM 안드로이드 앱!  (0) 2015.07.10
[Android GCM] 1. 준비  (0) 2015.07.10
[Android] Intent 예제  (0) 2015.05.19

댓글