목차
- 비동기 메시징
- FCM 에서의 pub/sub
- 포그라운드와 백그라운드에서의 메시징(알람 + 데이터) 구조
- 기능 구현
비동기 메세징
비동기
- 메시지를 보낸 순간 바로 응답을 기다리지 않아도 됨.
- FCM도 비동기 방식처리인데, 서버가 메시지를 큐(Queue) 에 저장해두고, 적절한 시점에 클라이언트에 전달하는 것
동기 방식과의 차이
동기 방식 | 요청 → 서버 → 응답올때까지 기다림 |
비동기 방식 | 서버에서 FCM 으로 메시지 발송 → 기다리지 않음 → 클라이언트는 나중에 수신 |
FCM 에서의 Pub/Sub
Publisher(Pub) : 메시지 전송
Subscriber : 특정 Topic 을 구독하고 있다가 메시지 수신
Pub/Sub System : Publisher 에게 메시지를 받아서 Subscriber 에게 전달하는 중간 다리 역할
동작 순서
- 서버가 특정 EndPoint 에 대한 Topic 에 메시지를 발행
- 해당 Topic 을 구독하고 있는 Subscriber 을 찾아 메시지를 보관 또는 즉시 전달하여 클라이언트(Subscriber) 가 비동기로 수신
특징
- 비동기 처리 : Subscriber 과 Publisher 가 동시에 실행되지 않아도 됨
- 느슨한 결합 : Subscrebier 과 Publisher 가 서로를 몰라도 됨
- 확장성 : 구독자 수가 많아져도 구조적으로 유연하 하나의 메시지를 여러 구독자에게 전달 가능
Foreground 와 Background 에서의 메시징(알림 + 데이터) 구조
포그라운드 상태
- 사용자가 앱을 켜고 현재 화면에서 사용 중인 상태 (ex. 인스타그램을 실행해서 피드를 보고 있을 때)
- 알림은 시스템이 자동으로 표시하지 않으며 앱에서 직접 처리해야함
- 데이터(메시지 내용)는 바로 수신 가능
백그라운드 상태
- 앱이 켜져는 있지만 화면에 보이지 않는 상태
* 홈 버튼 눌렀을때
* 다른 앱으로 전환했을때
* 잠금 화면 상태일때 등 - 알림은 시스템이 자동으로 알림을 띄어줌
- 데이터는 앱이 완전히 종료되었으면 수신 안될 수 있음
구현
구현 방법을 설명하기 전, FCM 에서 메시징 요청 방법은
1. HTTP v1 전송 요청
2. Admin SDK
이 두가지 방법이 있는데, 특징 차이를 살펴 보면
방식 | HTTP V1 API | Admin SDK |
인증 방식 | REST API (직접 HTTP 요청) | 공식 SDK 사용 |
메시지 구조 | 직접 JSON 구성 | SDK 메서드로 구성 |
유연성 | 높음 | 일부 최신 기능 미지원 및 커스텀 메시징이 필요한 경우 제한 |
설정 | 인증 토큰 발급과 헤더 구성 등을 직접 처리해야함 | 토큰 관리, 인증 등이 자동화되어 있어, 코드가 간결함. |
여기서 HTTP V1 방식은 최근에 나온 방식으로 앞서, 설명했다시피 유연성은 높지만, 설정해야할 요소들이 있다. 하지만 미리 설정해두고 나면 향 후 다른 최신 기능이나, 커스텀 메시징을 사용할때 매우 편리할 것이다.
그래서 필자는 HTTP V1 API 방식을 사용했다.
1. Firebase 콘솔에서 새프로젝트에서 Messaging 새 프로젝트 생성
2. FCM api 를 콜할 uri 경로 설정 (API 가이드에서 확인 가능)
String apiUri = "https://fcm.googleapis.com/v1/projects/" + PROJECTID + "/messages:send";
여기서 ProjectId 는 FCM 콘솔 -> 프로젝트 설정에서 확인 가능
3. FCM 에서 사용할 프로젝트에 대한 Secret Key 에 대한 정보와 FCM API V1 에서 사용할 Scopes 경로를 설정해준다.
private static String getAccessToken() throws IOException {
InputStream fis = new ClassPathResource(FIREBASE_CONFIG_URL).getInputStream();
GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(fis)
.createScoped(List.of(SCOPES));
googleCredentials.refresh();
return googleCredentials.getAccessToken().getTokenValue();
}
여기서 Secret Key 는 본인 프로젝트에서 발급 받으면 되고, SCOPES 는 https://developers.google.com/identity/protocols/oauth2/scopes
Google API의 OAuth 2.0 범위 | Authorization | Google for Developers
이 페이지는 Cloud Translation API를 통해 번역되었습니다. 의견 보내기 Google API의 OAuth 2.0 범위 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 문서에서는 필
developers.google.com
해당 링크에서 사용할 범위를 찾아서 해당 URI 링크를 넣어주면 된다. 필자는 FCM 관련 URI 를 사용하였다.
(구글에 있는 이유는 Firebase 는 구글에서 관리하는 개발 플랫폼이기 때문.)
4. 2 에서 설정한 Uri 경로와 요청 헤더를 FCM API 가이드에 맞게 설정하여, JSON 직렬화 후 양식에 맞게 요청한다.
public CMap sendMessage(CParam param) throws IOException {
String apiUri = "https://fcm.googleapis.com/v1/projects/" + PROJECTID + "/messages:send";
// http 헤더
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setBearerAuth(getAccessToken());
String json = CMapConverter.toJson(param);
HttpEntity<String> request = new HttpEntity<>(json, headers);
ResponseEntity<CResult> response = restTemplate.exchange(apiUri, HttpMethod.POST, request, CResult.class);
return response.getBody();
}
5. 요청
여기서 "topic" : all 은 모든 구독자에게 메세지를 보낸다는 의미. 만약 특정 사용자에게 보내고 싶다면 해당 사용자의 토큰 값을 알고 있어야 한다.
이렇게 API 가이드 양식에 맞게 요청을 하게 되면, Topic 을 구독한 subscriber 에게 정상적으로 문자가 오는 걸 확인할 수 있다.
끝
'JAVA (SPRING)' 카테고리의 다른 글
[JAVA] 카카오 알림톡 API 구현 (Ncloud 환경) (1) | 2025.04.15 |
---|---|
[JAVA] ObjectUtils, CollectionUtils (3) | 2025.03.06 |
[JAVA] LinkedHashSet (0) | 2025.03.05 |
IP-PBX 와 IP-Centrex 방식의 차이 (0) | 2025.02.18 |
OSI 7 Layer, TCP/IP 4Layer (0) | 2025.02.17 |