TIL

알람 기능 구현 방법

진진리 2024. 5. 5. 17:27
728x90

이번 학기 캡스톤으로 공유형 가계부 웹 서비스를 구현하는 프로젝트를 진행하고 있다.

가계부에 초대받았을 경우, 포인트를 받았을 경우, 댓글이 달렸을 경우 등 서비스 이용자에게 알람을 줄 필요성이 생겨 알람 기능을 구현하고자 한다.

그 전에 알람 기능을 구현하는 방법에는 어떤 방법이 있고 어떤 장단점이 있는지 알아보았다.

 

HTTP 통신에서는 클라이언트의 요청이 있을 경우에 서버가 응답을 하는 방식이고 비연결성이라는 특징을 가지고 있기 때문에 서버에서 실시간으로 클라이언트에 변경사항을 알리기 어렵다.

이에 대한 해결책, 즉 서버의 Event를 클라이언트로 보내는 방법으로 Polling, Long polling, Web socket, SSE 등이 있다.


Polling

  • 일정 주기를 가지고 서버에 요청을 보내는 방식
  • HTTP 통신을 기반으로 하기 때문에 호환성이 좋음
  • 주기에 따라 데이터 갱신이 늦거나, 서버에 부하가 발생할 수 있음

 

Long Polling

  • Polling과 비슷하지만 업데이트 시에만 응답을 보내는 방식
  • 서버 측에서 접속을 열어 두는 시간을 길게 함
  • 서버의 응답을 받은 클라이언트가 곧바로 request를 보내 다음 이벤트를 기다리게 함
  • Polling 방식보다 서버의 부담이 줄지만 이벤트가 자주 발생하는 경우 큰 차이가 없음

 

Web Socket

  • 서버와 웹 브라우저 사이에 실시간 양방향 통신이 가능한 방식
  • 웹 소켓 연결을 위한 TCP 핸드셰이크를 주고 받은 이후 지속적으로 연결이 유지됨
  • 실시간성이 요구되는 기능을 구현하는데 사용됨
  • 트래픽 양이 많아지면 서버에 큰 부담이 됨

 

SSE(Server-Sent Events)

  • 서버 -> 클라이언트 단방향 통신으로 실시간으로 데이터를 전송하는 방식
  • HTTP 프로토콜을 사용하여 구현이 쉬움
  • 연결이 끊이진 경우 자동으로 재연결
  • 연결 상태를 유지하기 위한 서버 부하 증가

 


구현하고자 하는 알림 기능의 경우 어느정도 실시간 방식이 필요하면서 클라이언트와 양방향으로 소통할 필요가 없어 SSE 방식을 채택하였다.

Spring framework 4.2부터 SSE 통신을 지원하는 SseEmitter 클래스를 통해 구현할 수 있다.

 

SseEmitter

  • 클라이언트와 유지되는 시간을 제한하는 타임아웃 설정을 지원
  • 서버에서 클라이언트로 텍스트 데이터를 전송
  • 비동기적으로 작동
  • 에러 핸들링 지원

작동 방식

  1. 컨트롤러에서 SseEmitter 객체를 생성합니다.
  2. SseEmitter를 사용하여 데이터를 전송하고 클라이언트와의 연결을 관리합니다.
  3. 데이터를 전송할 때는 SseEmitter의 send() 메서드를 사용합니다.
  4. 연결이 완료되면 SseEmitter를 종료합니다.

예시 코드

@Controller
public class MyController {

    @GetMapping("/stream-data")
    public SseEmitter streamData() {
        SseEmitter emitter = new SseEmitter();
        
        // 비동기 작업 수행 후, 데이터를 스트리밍합니다.
        CompletableFuture.supplyAsync(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    emitter.send("Data " + i);
                    Thread.sleep(1000); // 1초마다 데이터 전송
                }
                emitter.complete(); // 데이터 전송 완료
            } catch (Exception e) {
                emitter.completeWithError(e); // 에러 처리
            }
            return null;
        });

        return emitter;
    }
}

 

참고

https://velog.io/@black_han26/SSE-Server-Sent-Events

 

SSE (Server-Sent-Events) 란?

SSE란 무엇인지 알아보고, Spring을 통해 구현을 해보았다.

velog.io

https://develoyummer.tistory.com/112

 

[프로젝트]알림 기능 구현(SSE, Spring AOP)

💡알림기능 사용목적 yata project에서는 앱 사용의 편의성을 위해 카풀 신청 완료시, 또는 내가 쓴 게시글에 신청 요청이 왔을 때 알림 기능을 넣기로 결정하였고, 로그인 상태일 때 실시간으로

develoyummer.tistory.com

https://taemham.github.io/posts/Implementing_Notification/

 

[백엔드 스프링부트] 알림 기능은 어떻게 구현하는게 좋을까?

This is a wannabe backend developer’s dev blog.

taemham.github.io