Firbase Cloud Messaging Http v1 api 를 사용하려면 Google API 대쉬보드에 API 사용을 등록해야 하는데 방법은 다음과 같다.

 

 

1. url 접속 

https://console.developers.google.com/apis/dashboard

 

 

1. Firebase Console에서 생성한 프로젝트를 선택합니다.

2. Firebase Cloud messaging API를 검색합니다.

 

 

 

 

3. 사용설정을 선택합니다.

해당 글에서는 FCM 서버로 메시지를 전송하는 protocol에 대해서만 살펴볼 것이며,

 

SDK를 이용한 클라이언트 작업은 https://firebase.google.com/docs/cloud-messaging 에서 자세히 확인할 수 있다.

 

FCM Provider 에 대한 예제는 https://github.com/chulman/firebase-cloud-messaging 에 작성하였다.

 

Protocol

- 기본적으로 HTTP와 xmpp를 통해 메시지를 전송할 수 있다.

 

HTTP

XMPP

UpStream/DownStream

다운스트림 전용

최대 4kb의 데이터

업스트림/다운스트림

최대 4kb의 데이터

메시징 방식

Request & Response

-> 응답받기 전까지 다른 메시지를 보내지 못하도록 차단.

승인 또는 실패(ACK or NACK Json 인코딩 XMPP 메시지 형태)를 비동기적으로 보냄

JSON

HTTP POST로 전송된 

JSon message

JSON MESSAGE가 XMPP 메시지로 캡슐화 됨.

일반텍스트

HTTP POST로 전송된

일반 텍스트 메시지

지원하지 않음.

멀티캐스트 다운스트림이 여러 등록 토큰으로 전송

JSON Message 형식에서 지원

지원하지 않음.

 

HTTP API

-  Http API로 메시지를 전송하는 포맷은 http api 와 http v1 api 2가지가 존재한다. 

 

-  http v1 api를 사용하려면 google api 대쉬보드를 통해 등록해야 한다. (참조: Google API 대쉬보드에 FCM API 설정하기)

 

 

1. http api VS http v1 api

 

- http api는 가장 심플한 레거시 방식으로 오랫동안 많은 사람들이 써왔던 방식이다. 특정 url로 규격에 맞는 json 포맷을 통해 전송하기 만하면 된다.

 

- http v1 api는 http api를 보안한 api라고 생각하면 될 것 같다. 가장 크게 강조하는 2가지는 보안과 멀티 플랫폼이다.

 

   + (1) 보안 : http v1 api 는 oauth 방식을 통해 fcm 서버와 연결하고 인증한다. (때문에 좀 더 까다롭다..) 

   + (2) 멀티 플랫폼 : 기존 http api를 통해 메시지를 전송할 때는 보내는 형식이 기기 중심적이었다. 여러 기기를 묶어서 공통된 메시지를 보낼 수 밖에 없었는데, 이를 보완하고 플랫폼 별(ios, android..) 다양한 메시지 내용과 포맷을 하나의 json 포맷으로 구성할 수 있고 때문에 한 번의 전송으로 여러 플랫폼에 메시지 전송이 가능하다.

 

(해당 fcm 블로그에서 자세한 사항을 확인할 수 있다.) - https://firebase.googleblog.com/2017/11/whats-new-with-fcm-customizing-messages.html

 

 

 

 

2. request header 

 

- request option : 메시지를 전송 할 때는 POST 방식이어야 한다.

- url : 

   + http api : https://fcm.googleapis.com/fcm/send    

   + http v1 api: https://fcm.googleapis.com/v1/{parent=projects/*}/messages:send 

 

- port : 주의할 점은 htps를 통한 연결이 때문에 443 포트에 대한 방화벽 정책이 허용되어야 한다.

 

- content type : application / json

- parameter : 

      + http api : "authrization" :  key = "api 서버 키"

      + http v1 api: "authrization" :  bearer + "api 서버 키"

 

 

 

3. request body

 

- 메시지를 전송할 때 body에 json 형식의 payload를 보낼 수 있는데 format은 아래에서 확인할 수 있다.

   +  https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ko

 

FCM 메시지 정보  |  Firebase

Firebase 클라우드 메시징(FCM)은 다양한 메시징 옵션과 기능을 제공합니다. 이 페이지의 정보는 다양한 유형의 FCM 메시지에 관한 이해를 돕고 FCM으로 구현할 수 있는 기능을 소개하기 위한 내용입니다. 메시지 유형 FCM을 통해 2가지 유형의 메시지를 클라이언트에 보낼 수 있습니다. 알림 메시지: 종종 '표시 메시지'로 간주됩니다. FCM SDK에서 자동으로 처리합니다. 데이터 메시지: 클라이언트 앱에서 처리합니다. 알림 메시지에는 사용자에게

firebase.google.com

 

3.1 http api 요청 포맷 예

 

아래 포맷을 보면 특정 토큰(기기)에 notification이라는 메시지 형식을 통해 알림 형태를 지정하며, 커스텀 데이터를 추가해서 사용자가 메시지를 좀 더 다양하게 파악 할 수 있다.

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    },
    "data" : {
      "Nick" : "Mario",
      "Room" : "PortugalVSDenmark"
    }
  }
}

 

- 여러 토큰에 타겟해서 보낼 경우 registration_ids를 설정해서 보낼 수 있는데, 배열 갯수의 제한은 1000개 이다. 즉 한 번 전송시 1000개까지 밖에 전송할 수 없다.

 

{
  "message":{
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    },
    "data" : {
      "Nick" : "Mario",
      "Room" : "PortugalVSDenmark"
    },
    "registration_ids": ["bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", ...] 
  }
}

 

- 때문에 FCM에서는 TOPIC이라는 키를 활용해서 좀 더 많은 디바이스에 한번에 전송할 수 있는 방법을 제공한다.  다음과 같이 메시지를 전송하면 "NEWS"라는 토픽을 등록한 기기에 모두 전송한다.

 

{
  "message":{
    "topic" : "NEWS",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    },
    "data" : {
      "Nick" : "Mario",
      "Room" : "PortugalVSDenmark"
    }
  }
}

 

3.2 http v1 api 요청 포맷 예

- 여러 플랫폼에 전송할 수 있는 형식을 사용할 수 있다.

 

{
  "message":{
    "topic":"subscriber-updates",
    "notification":{
      "body" : "This week's edition is now available.",
      "title" : "NewsMagazine.com",
    },
    "data" : {
      "volume" : "3.21.15",
      "contents" : "http://www.news-magazine.com/world-week/21659772"
    },
    "android":{
      "priority":"normal"
    },
    "apns":{
      "headers":{
        "apns-priority":"5"
      }
    },
    "webpush": {
      "headers": {
        "Urgency": "high"
      }
    }
  }
}

 

 

 

4. response header & Error Code

- 참조: https://firebase.google.com/docs/cloud-messaging/http-server-ref?hl=ko#error-codes

 

 

 

5. response body

- 마찬가지로 http api와 http v1 api의 response body는 다르다.

 

 

5.1  response body

 

- 전송 시 registration_ids 키값 에 5개의 기기를 포함했을 때, body 다음과 같은 형식이 될 것이고 5기기의 결과 값이 result 배열에 포함된다.

 

 

- http v1 api로 전송시 성공한다면 다음과 같은 형식으로 응답을 내 뱉는다.

 

{"name": "projects/{project-name}/messages/2280331808525169080"}

 

 

- 가장 큰 문제점은 에러가 발생했을 때 처리 부분인데, 에러코드가 너무 빈약하다는 점이다. 자세하게 확인하려면 admin sdk를 통해 따로 요청하는 등 방법이 존재하는데 이에 따른 비용이 더 생길 우려가 있다.

 

구조

 

https://firebase.google.com/docs/cloud-messaging/fcm-architecture

 

 

 

개인적으로 Firebase 레퍼런스는 굉장히 친절하고 쉬운편이라고 생각해서 사이트를 조금만 참조해도 누구나 쉽게 이해할 수 있다고 생각하며, 개인적인 의견만 코멘트해 본다.

 

 

(1) : GUI 나 HTTP/XMPP 프로토콜을 사용할 수 있는 환경이라면 어디서든 메시지를 전송할 수 있다. 파이어베이스 sdk 라이브러리를 사용할 수 있는 환경은 https://firebase.google.com/docs/libraries에서 확인 가능하다.

 

(2) : 클라이언트에게 메시지 전송을 하려면 FCM 백엔드 서버에 클라이언트 정보를 같이 전달해줘야 하는데 토픽과 instance가 필요하다.

여기서 토픽은 클라이언트 정보를 묶는 topic (pub/sub 모델에서 자주 등장하는 topic 으로 생각해도 좋다) 을 전달해주거나 고유한 token(device 정보를 알 수 있는 uuid 값)을 함께 전달해야 한다.

 

(3) : FCM 백엔드 서버는 데이터를(json 혹은 xml) 분석하고 플랫폼에 맞게 전송 서버를 타겟할 것이다;.

 

(4) : 전송했던 타겟 정보와 일치한 클라이언트는 메시지를 수신한다.

 

 

 

LifeCycle

 

위의 플로우로 메시지를 전송하려면 반드시 선행해야하는 작업이 있는데, 당연하겠지만 메시지를 수신할 클라이언트는 자신의 정보를 FCM 서버에 등록해야 한다는 점이다. 순서는 다음과 같다.

 

 

1. 클라이언트는 자신의 정보( 토픽, 인스턴스) 를 FCM 백엔드 서버에 등록해야 한다.

2. 메시지를 전송할 주체 (3rd-parry 서버 혹은 모바일) 는 등록된 정보를 획득해야 하며, 해당 정보로 다운스트림 메시지를 전송한다.

 

 

Firebase

파이어베이스(Firebase)는 2011년 파이어베이스(Firebase, Inc)사가 개발하고 2014년 구글 인수된 모바일 및 웹 애플리케이션개발 플랫폼이다.

 

Firebase Cloud Messaging

Firebase 클라우드 메시징(FCM)은 무료로 메시지를 안정적으로 전송할 수 있는 교차 플랫폼 메시징 솔루션

구글에서는 GCM이라는 독자적인 플랫폼이 존재했었는데, 파이어베이스를 인수한 이후 GCM을 고도하여 FCM에 집중해오고 있다.

GCM은 2019년 5월 서비스 지원을 중단하게 되었다. 때문에 대부분 Push 솔루션을 구현한 회사들에서는 FCM으로 마이그레이션 작업을 준비했을 것이며 나 또한 그러했다.

(서비스 중단에 따라 반드시 변경해야 될 작업은 https://developers.google.com/cloud-messaging에서 확인해 볼 수 있다.)

 

그래서 어떻게 동작할까?

네티 인 액션

출처:https://firebase.google.com/docs/cloud-messaging/images/messaging-overview.png

 

 

 

다시 정리하면 FCM은 메시지 전송 플랫폼이다. 위 그림은 FCM이 어떻게 메시지를 클라이언트에게 전송하는지 모든 걸 나타낸다.

 

flow

(1) Firebase Console GUI 에서 메시지를 전송

 

(2) 3rd-party-server 혹은 모바일 클라이언트 에서 http 혹은 xmpp 프로토콜을 통해 메시지를 전송 

      - firebase는 손쉽게 메시지를 전송하도록 library를 제공한다.

 

(3) firebase 서버에서는 특정 기기로 메시지 전송 요청을 받으면 장치(ios, android, web)으로 알림을 전송

 

(4) 클라이언트는 메시지 수신

 

 

정리

- FCM을 사용함으로써 얻는 장점은 간단하다. cloud 서비스를 이용함으로써 서버리스 아키텍쳐를 구성하고 메모리나 CPU의 오버헤드, 트래픽, 서버 등 관리포인트가 크게 줄어들기 때문에 비용을 크게 감소시킬 수 있다. 특히 FCM은 완전히 무료다.  (물론 완전히 관리하지 않아도 된다는 말은 아니다.. 사용자 관리, 토픽 등.. 여러가지 있다.. ) 

 

 

- Bound Resource(한정된 자원): 다중 스레드 환경에서 사용하는 한정적인 자원

- Mutual Exclusion(상호 배제): 한 번에 한 스레드만 공유자원을 사용할 수 있다.

- Starvation(기아): 쓰레드가 오랫동안 자원을 기다리는 상태

- Dead Lock(데드락): 여러 쓰레드가 서로 끝나길 기다리느라 진행하지 못하는 상태

- Live Lock(라이브락): 락을 거는 단계에서 각 스레드가 서로 방해한다.

 

- 세마포어(Semaphore) : 공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막는 것

 

- 뮤텍스(Mutex) : 공유된 자원의 데이터를 여러 쓰레드가 접근하는 것을 막는 것

 

- 경쟁상태(Race Condition) :  공유 자원에 대해서 여러 개의 프로세스가 동시에 접근을 시도하는 상태

 

- 선점불가(No Preemtion): 한 스레드가 다른 스레드로부터 자원을 빼앗지 못하는 것

 

'기타' 카테고리의 다른 글

nginx configuration  (0) 2020.01.07
DB 순위 비교 사이트  (0) 2019.07.31
Ant vs Maven Vs Gradle  (0) 2019.04.10
Thread 분석  (0) 2018.11.19
Oracle JDK 유료화의 논쟁, OpenJDK와의 차이  (0) 2018.11.03

요약

 

VPC(Virtual Private Cloud)

 

- 사용자에게 제공하는 가상 네트워크 사설 망.

- VPC를 적용하면 EC2 인스턴스 간의 네트워크 복잡성을 줄일 수 있으며, 각 각 네트워크 환경의 독립적인 설정이 가능해진다.

 

Subnet

 

- VPC 내에서 더 작은 범위로 나눈 것

- 더 많은 네트워크를 구성하기 위한 목적

- AWS의 가용영역에 의해 subnet이 나눠진다.

- 인터넷과 Public Access가 가능하면 puplic subnet, 불가능하면 private subnet

 

Router

 

- 라우터란 둘 혹은 그 이상의 네트워크와 네트워크 간 데이터 전송을 위해 최적 경로를 설정해주며 데이터를 해당 경로를 따라 한 통신망에서 다른 통신망으로 통신할 수 있도록 도와주는 인터넷 접속 장비이다.

 

 

CIDR 

 

- Classless Inter-Domain Routing(CIDR)로 클래스 없는 도메인 간 라우팅 기법으로 IP주소를 할당하는 최신 방법

-  ip 주소 뒤에 /로 구분하고, 서브넷 마스크의 비트수를 적어 표시하는 방법 

- ex) 10.0.0.16/16

 

 

NETMASK

 

- 네트워크 주소 부분의 비트를 1로 치환한 것이 netmask

- IP 주소와 netmask를 and 연산하면 네트워크 주소를 얻을 수 있다.

 

Routing Table

 

- 네트워크 이동에 대한 이정표

- 상위 그림의 Subnet A에 존재하는 인스턴스들에 대한 네트워크 요청은 로컬(local)을 찾게 되어 있다.

- 하지만 외부로 나가는 요청은 인터넷 게이트웨이(igw-id)가 대상이 된다.

 

 

Internet Gateway

 

- 인터넷과 연결해주는 중간 매개체

- 라우팅 테이블에서 상위부터 매칭되는 IP에 대한 타깃을 찾고, 없으면 가장 마지막 igw ip를 찾게 된다.

 

NAT Gateway

 

- private subnet이 인터넷과 연결하기 위한 아웃바운드 instance

- private network가 외부에서 요청되는 인바운드는 필요 없더라도 인스턴스의 펌웨어나 혹은 주기적인 업데이트가 필요하여 아웃바운드 트래픽만 허용되야할 경우가 있다. 이때 퍼블릭 서브넷상에서 동작하는 NAT 게이트웨이는 private subnet에서 외부로 요청하는 아웃바운드 트래픽을 받아 인터넷 게이트웨이와 연결한다.

 

 

NACL (Network ACL) 과 보안 그룹

 

- 네트워크 ACL과 보안그룹은 방화벽과 같은 역할을 하며 인바운드 트래픽과 아웃바운드 트래픽 보안정책을 설정할 수 있다.

- 먼저 보안그룹은 Stateful 한 방식으로 동작하는 보안 그룹은 모든 허용을 차단하도록 기본 설정되어있으며 필요한 설정은 허용해주어야 한다. 

- 네트워크 ACL은 Stateless하게 작동하며 모든 트래픽을 기본 설정되어있기 때문에 불필요한 트래픽을 막도록 적용해야 한다. 서브넷 단위로 적용되며 리소스 별로는 설정할 수 없다. 네트워크 ACL과 보안 그룹이 충돌한다면 보안 그룹이 더 높은 우선순위를 갖는다.

 

 

 

 

https://medium.com/harrythegreat/aws-%EA%B0%80%EC%9E%A5%EC%89%BD%EA%B2%8C-vpc-%EA%B0%9C%EB%85%90%EC%9E%A1%EA%B8%B0-71eef95a7098

https://docs.aws.amazon.com/ko_kr/vpc/latest/userguide/VPC_Subnets.html

https://www.digitalocean.com/community/tools/nginx

'기타' 카테고리의 다른 글

동시성 관련 기본 용어  (0) 2020.03.14
DB 순위 비교 사이트  (0) 2019.07.31
Ant vs Maven Vs Gradle  (0) 2019.04.10
Thread 분석  (0) 2018.11.19
Oracle JDK 유료화의 논쟁, OpenJDK와의 차이  (0) 2018.11.03

객체지향 5원칙

 

SRP(단일 책임 원칙), OCP(개방-폐쇄 원칙), LSP(리스코프 치환 원칙), DIP(의존 역전 원칙), ISP(인터페이스 분리 원칙)

 

 

1) SRP (Single Responsibility Principle)

- 모든 클래스는 단일 책임을 갖는다.

- 하나의 클래스에 너무 많은 책임을 부과하지 말자. 예를 들어, 로또 생성 클래스는 로또 생성의 책임만 다해야 한다. 로또를 Shuffle하거나 추출하는 기능의 책임을 부과하지 말자.

 

 

2) OCP(Open Closed Principle)

- 확장에 대해서는 열려 있어야 하고 수정에 대해서는 닫혀 있어야 한다.

- 무엇이 변하는지, 무엇이 변하지 않는지에 집중해야 한다.

- 정의된 행위를 수정하지 못해야 한다. 예를 들면 추상 클래스를 들 수 있는데, 추상화된 클래스의 추상 메소드는 오버라이딩 되어 재정의할 수 있고 추가 기능이 가능한 메소드를 정의할 수 있다. 하지만 하위 클래스에서 해당 추상 메소드는 변경하지 못한다.

 

 

3) LSP(Liskov Substitution Principle)

- sub type은 언제나 base type을 대체할 수 있어야 한다.

- LSP는 상속의 룰이다. OCP를 위반하지 않도록하는 원칙이다.

 

 

4) ISP(Interface Segregation Principle)

- 인터페이스를 클래스에 특화되도록 분리한다.

- SRP와 밀접하며 ISP가 지켜지면, SRP가 지켜질 수 있다.(SRP가 지켜진다고 해서 ISP가 지켜지는 것은 아니다.)

-인터페이스가 너무 비대해질 경우 문제가 생길 수 있다. ISP 를 위반 하는 예를 들면 다음과 같다.

 

public interface Analyzer {
	
    public void analyze(SocketChannel channel, byte[] data);
    public void analyze(HttpChannel channel, String data);
}


public class tcpAnayzer implements Analyzer {
	
    public void analyze(SocketChannel channel, byte[] data){
    ...
    }
   	// ??? 구현하지 않음
    public void analyze(HttpChannel channel, String data){
    }

}

public class HttpAnalyzer implements Analyzer {
	
    // ??? 구현하지 않음
    public void analyze(SocketChannel channel, byte[] data){
    }
    public void analyze(HttpChannel channel, String data){
    ...
    }

}

 

위와 같이 Analyzer 인터페이스라고해서 TCP 채널에서 발생한 데이터도 구현하고, Http 채널에서 발생한 데이터도 구현하도록 모두 정의 해놓으면

해당 인터페이스를 구현한 클래스는 모든 기능에 대해 강요 받게 된다.  

 

ISP의 핵심은 변화 대응에 대해 유연해야하고, 일반적인 인터페이스보다 구체적인 여러개의 인터페이스를 구현해야 한다는 점이다.

 

 

 

5) DIP(Depenency Inversion Principle)

- 의존 관계를 맺을 때, 변하기 쉬운 것 보다는 변하기 어려운 것에 의존해야 한다. (OCP와 밀접)

- 예를 들면.. 구체화 된 클래스에 의존하지 말고 추상화된 인터페이스에 의존하라.

 

 

 

https://vandbt.tistory.com/41

http://wiki.c2.com/?LiskovSubstitutionPrinciple

 

 

 

 

 

 

 

 

+ Recent posts