ex. SMTP
ex. POP3, IMAP (이메일 서버에서 사용자에게 전달)
알림 기능은 사용자의 이벤트를 감지하여 서버에서 데이터를 보내주는 푸시 기법을 사용하며, 대부분 클라이언트의 요청에 대한 응답보다 서버에서 일방적으로 변경을 감지하여 보내준다.
이때 실시간으로 서버의 변경 사항을 갱신해주어야 하는데, 이 말은 즉, 알림 기능이 “실시간 통신” 의 기반 하에 구현되어야 함을 의미한다. 실시간으로 서버와 통신을 해야 하는 경우, 매번 HTTP 통신을 요청하기에는 연결의 효율성이 떨어진다.
서버에서 실시간 통신을 하는 방법은 무엇이 있을까?
일정 주기를 가지고 서버의 API를 호출하는 방식
이는 HTTP 통신의 기반을 유지하므로, 호환성이 좋지만 업데이트 주기를 어떻게 설정하느냐에 따라 데이터의 불일치 또는 서버 부하의 문제가 따를 수 있다.
업데이트 발생 시에만 응답을 보내는 방식 (Polling과 유사)
서버로 요청이 들어올 경우, 일정 시간동안 대기했다가 요청한 데이터가 업데이트 되면 엡 브라우저에게 응답을 보낸다. 따라서 연결이 된 경우에는 실시간으로 데이터를 반영할 수 있다.
하지만, 요청이 잦아지면 트래픽이 많아져 Polling과 마찬가지로 서버 부하가 커진다는 단점이 따른다.
요청을 보내고 응답을 보낸 후, Connection을 종료하는 것이 아니라 이를 유지한 채로 다음 응답을 계속해서 받는 방식
서버가 일정 시간동안 요청을 대기시키고, Chunked 메시지를 이용해 응답 시 연결을 계속 유지해야 하므로 클라이언트에서 서버로 데이터를 보내는 게 힘들어진다.
서버와 클라이언트 간에 소켓 connection을 유지하여 언제든 양방향 통신 또는 데이터 전송을 가능하게 하는 방식
웹 소켓은 기존의 단방향 HTTP 프로토콜과 호환되어 양방향 통신을 제공하기 위해 개발된 프로토콜로, 접속까지는 HTTP 프로토콜을 이용하고 그 이후의 통신은 자체 WebSocket 프로토콜로 통신한다.
웹 소켓은 한 번 연결을 맺으면 연결을 해제하기 전까지 유지되므로, 연결을 맺고 끊는 연결과정을 없앨 수 있을 뿐만 아니라, 양방향 통신이 가능하기 때문에 클라이언트가 요청을 하지 않아도 서버가 제공해야 할 데이터를 보내줄 수 있다. 웹 소켓은 한번에 주고받는 데이터의 양이 HTTP에 비해 확연히 적기 때문에 계속 데이터를 주고 받아야 하는 서비스에는 적절하지 않다. 주로 변경 사항에 빠르게 반응해야 하는 채팅이나, 리소스 상태에 대한 지속적인 업데이트가 필요한 문서 동시 편집 등의 서비스에 많이 사용된다.
웹 소켓 프로토콜인 RFC 6455는 단일 TCP 연결을 통해 클라이언트와 서버 사이에 전이중 방향 통신(2-way Communication) 채널을 설정하는 표준화된 방법을 제공한다. HTTP 환경에서, HTTP와는 다른 TCP 프로토콜이나, Port 80, 443 등을 사용해 HTTP를 통해 작동하며 기존 방화벽 규칙 및 HTTP 규격인 CORS 적용, 인증 등의 과정을 재사용할 수 있도록 설계되었다.
따라서, HTTP 통신의 Request/Response 헤더가 불필요하게 크게 되는 문제를 해소하여 최초 접속 시에만 헤더 정보를 이용하고 그 이후부터는 더이상 보내지 않고도 처리가 가능해진다.
💬 정리하자면, 요청을 보내야 서버로부터 응답이 오는 기존의 양방향 통신 방식을 단순화하여 **하나의 HTTP 접속으로 양방향 메시지를 자유롭게 주고받을 수 있도록 구성**된 단순 API 이다.❕ 웹 소켓은 연결 요청에 대해 HTTP를 통해 Switching 및 HandShaking이 이루어진다. 결과적으로 모든 어플리케이션 내 메세지는 한 개의 초기 연결을 위한 URL, 즉 동일한 TCP 연결을 통해 흐른다.
*클라이언트와 서버가 메세지 시맨틱에 동의하지 않으면 메세지를 라우팅하거나 처리할 수 없다.
❕ TCP는 이진 데이터만 주고받을 수 있는 반면, 웹 소켓은 바이너리와 텍스트 데이터를 모두 주고받을 수 있다.
🧐 알림 기능에서 사용한다면?WebSocket은 양방향 통신에 적합하다.
알림 서비스는 양방향의 통신보다는 주로 알림을 받는 사람에서의 요청이 없이 서버의 응답을 단방향으로 보내기만 해주는 서비스이기 때문에, 웹 소켓을 이용하는 방식은 too much.. 비효율적이라는 것이다.
서버의 특정 이벤트를 구독하여, 이벤트 발생 시마다 데이터를 보내주는 방식
→ 지속적인 스트리밍 기술
웹 소켓보다 가벼운 단방향 통신 방식의 SSE는 클라이언트가 서버로부터 데이터를 받을 수만 있다. 별도의 프로토콜 사용 없이 HTTP만 사용하여 처음 연결을 요청한 이후에, 연결된 상태를 유지하고 서버가 일방적으로 데이터를 전송하게 된다.
이때 최대 동시 접속 횟수는 제한되어 있다는 단점이 있다. (HTTP/1.1 - 브라우저 당 6개, HTTP/2 - 브라우저 당 100개)
위 세 가지 방식을 고려해볼 수 있는데, 1번 방식은 위에서 언급했듯 알림 기능에 최적화되지 않으므로, 2번, 3번 방식을 더 깊이 공부해보고 실습 예제를 통해 구현해보고자 한다.
SSE를 이용한 실시간 알림 구현
Android, iOS 및 웹 애플리케이션의 메시지 및 알림을 위한 크로스 플랫폼 메시징 솔루션
- 모든 사용자에게 알림 메시지를 전송할 수도 있고, 그룹을 지어서 메시지를 전송할 수 있도록 무료 지원해준다.
- HTTP Web Push 프로토콜인 'RFC8030’ 사용
<aside>
💫 앱 서버 → 클라이언트 앱으로 다운 스트림 메시지를 보낼 수 있을 뿐만 아니라, 클라이언트 앱 → 앱 서버로 업 스트림 메시지를 보낼 수도 있다. </aside>
메세지 종류 | 알림 가능 여부 | 알림 저장 개수 | 알림 처리 방법 |
---|---|---|---|
알림 메시지 | 가능 | 여러 알림을 저장하나, OS 환경마다 다르다. | 앱이 백그라운드 일 때 |
데이터 메시지 | 가능 | 1개의 알림만 저장 | 앱이 포그라운드 일 때 |
종류 | 대상 수 | 설명 |
---|---|---|
단일 기기 (특정 기기) | 1개 | 하나의 기기(앱 기준) |
기기 그룹 (여러 대의 기기) | 20개 | 알림 키에 허용되는 그룹 |
특정 주제 구독 및 주제 구독자 | 1000개 | 등록 토큰에 구독된 기기 |
@Scheduled
사용사용자가 서버를 경유하여 실시간으로 푸시 메시지를 받게 된다.
서버를 경유해서 푸시 메시지를 받으려면, 사용자가 항상 서버에 접속해있어야 하는데 이는 리소스 낭비가 크다.
→ FCM으로 구현할 시, 클라우드 메시징 서버를 중간에 둠으로써 낮은 배터리와 네트워크의 사용만으로 실시간으로 메시지의 송수신 처리가 가능해진다.
또한, 플랫폼(Android, iOS, Web)에 따라 APNS(Apple Push Notification Service), GCM(Google Cloud Messaging) 의 푸시 알림 서비스를 별도로 사용하여 클라이언트가 각각 구축을 해야 한다.
→ GCM: 서버에서 Android 디바이스의 어플리케이션으로 데이터를 전송하도록 도와주는 서비스
단말에서 GCM으로 register 요청
GCM에서 register 성공 후 registration id 전송
third-party server로 registration id 전송
a. registration id 값과 알림 메시지를 GCM으로 전송
b. 해당 registration에 맞는 단말에 알림 메시지 전송
→ APNS: 서버에서 새로운 데이터를 모니터링하며 영구적 보안 채널을 통해 APN와 공급자를 연결하고, 대상 장치에 알림을 보내는 서비스
*Apple 기기로 알림을 보내려면 APNS는 필수이며, FCM과 같이 사용하는 경우 Apple Developer에서 key를 등록하고 APN 인증키를 받아 FCM에 넣어주어야 한다. → 클라 쪽에서 설정!
http://devstory.ibksplatform.com/2017/09/gcm-apns.html