요구사항

SSE (Server - Sent Events)

sse는 http스트리밍을 통해 서버에서 클라이언트로 단방향의 push Noti를 할 수 있는 HTML표준 기술이다.

전통적인 애플리케이션은 요청 단건에 대해 서버가 응답하는 방식이지만, SSE를 이용해 서버에서 클라이언트로 Real-Time Push Notification을 전송할 수 있다.

1. 스프링 부트 어플리케이션 만들기

Untitled

Untitled

2. Temperature 도메인 작성

package com.temperature.stream.domain;

// @Getter 써도 private속성은 가져올 수 없음..
public class Temperature {
    private final double value;

    public Temperature(double value) {
        this.value = value;
    }

    public double getValue() {
        return value;
    }
}

3. Temperature Controller 작성

@RestController
public class TemperatureController {
    private final Set<SseEmitter> clients = new CopyOnWriteArraySet<>();

    @GetMapping(value = "/temperature-stream") // 요청 핸들러
    public SseEmitter events(HttpServletRequest request){
        SseEmitter emitter = new SseEmitter();
        clients.add(emitter);

        emitter.onTimeout(()->clients.remove(emitter));
        emitter.onCompletion(()->clients.remove(emitter));
        return emitter; // 클라이언트 요청 시 새로운 SseEmitter를 생성하여 클라이언트 목록에 등록과 동시에 이를 반환
    }
    @Async // 메서드를 비동기 실행한다. 별도로 구성된 스레드 풀에서 호출됨
    @EventListener // 스프링으로부터 이벤트를 수신하기 위한 어노테이션. 온도 이벤트를 수신할 때 handleMsg 호출
    public void handleMessage(Temperature temperature){
        List<SseEmitter> deadEmitters = new ArrayList<>();
        for (SseEmitter emitter : clients){
            try{
                emitter.send(temperature, MediaType.APPLICATION_JSON); // 각 이벤트들에게 병렬로 메시지 전송
            }catch (Exception ignore){
                deadEmitters.add(emitter);
            }
        }
        clients.removeAll(deadEmitters); // 활성 클라이언트에서 전송 실패한 연결 제거
    }
}

4. Temperature Sensor 도메인 작성(이벤트 발행)