🕊️ SSE와 WebSocket, 왜 실시간 통신의 라이벌이 되었을까?

이 포스팅에서는 SSE와 WebSocket의 특징과 사용법을 비교해 보면서, ‘내 프로젝트에서는 어떤 녀석이 주인공일까?’에 대한 답을 찾아보도록 하겠습니다.

 

SSE (Server-Sent Events)

SSE는 마치 선생님이 수업 시간 내내 일방적으로 학생들에게 말하는 것과 같습니다. 학생(클라이언트)은 계속해서 듣고 받아 적어야 하죠.

  • 학생: 선생님, 질문이 있습니다

  • SSE: 미안, 넌 질문할 수 없어!


SSE는 서버가 클라이언트에게 일방적으로 데이터를 푸시할 때 쓰입니다. HTTP 기반이라서 프록시나 방화벽이 거부하지 않습니다.

 

서버에서 매초마다 데이터를 보낸다고 상상해 볼까요?

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;

@RestController
public class SSEController {

    @GetMapping("/sse")
    public void streamEvents(HttpServletResponse response) throws IOException {
        response.setContentType("text/event-stream");
        response.setCharacterEncoding("UTF-8");

        PrintWriter writer = response.getWriter();
        for (int i = 1; i <= 5; i++) {
            writer.write("data: SSE 이벤트 #" + i + "\n\n");
            writer.flush();
            try {
                Thread.sleep(1000);  // 1초마다 이벤트 전송
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        writer.close();
    }
}
const eventSource = new EventSource('/sse');

eventSource.onmessage = function(event) {
    console.log("새 이벤트 수신:", event.data);
};

eventSource.onerror = function() {
    console.error("SSE 연결 오류 발생");
};

장점:

  • SSE는 자동 재연결을 지원합니다.

  • 설정이 간단해서 빨리 구현하고 싶은 개발자에겐 최적입니다.

단점:

  • 오직 단방향입니다. 클라이언트는 서버에 말을 걸 수 없어요. (서운하지만 어쩔 수 없습니다.)

  • 데이터를 텍스트로만 보내는 게 편합니다. 이미지나 비디오 전송은 꿈도 꾸지 마세요.

 

WebSocket

WebSocket은 연애 초기의 커플 같아요. 둘이 채팅하느라 시간 가는 줄 모르죠. 양방향 통신이 가능하기 때문에 서버와 클라이언트가 자유롭게 대화를 주고받습니다.

  • A: "지금 뭐 해?"

  • B: "지금 네 메시지 받았어. 다시 보낼게!"


이제 서버와 클라이언트가 한바탕 신나게 대화하는 예제를 보겠습니다.

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new TextWebSocketHandler() {
            @Override
            protected void handleTextMessage(WebSocketSession session, TextMessage message) 
                    throws Exception {
                session.sendMessage(new TextMessage("에코: " + message.getPayload()));
            }
        }, "/ws");
    }
}
const socket = new WebSocket('ws://localhost:8080/ws');

socket.onopen = () => {
    console.log('WebSocket 연결 성공!');
    socket.send('안녕, 서버!');
};

socket.onmessage = (event) => {
    console.log('받은 메시지:', event.data);
};

장점:

  • 양방향이라 서버와 클라이언트가 마음껏 수다를 떨 수 있습니다.

  • 텍스트뿐만 아니라 바이너리 데이터도 전송할 수 있어요. (그림도 보낼 수 있다는 얘기죠!)

단점:

  • 설정이 조금 귀찮습니다. 방화벽에 걸리기 쉽고, 초기 핸드셰이크까지 해야 하니까요.

  • 재연결? 그런 거 없습니다. 알아서 다시 연결할 방법을 짜야 해요.

 

마무리 및 결론

  • SSE는 "너 듣기만 해, 내가 다 말해줄게" 스타일에 적합합니다. 실시간 뉴스나 알림처럼 서버에서 클라이언트로만 정보가 흐를 때 좋습니다.

  • 반면에, WebSocket"같이 떠들자!" 스타일입니다. 채팅, 게임처럼 상호작용이 필요한 경우 선택하세요.

 

저는 개인적으로 어드민 UI에서 서버 로그를 실시간으로 출력할 때 SSE를 사용했습니다. 클라이언트가 서버에게 말할 필요가 없었기 때문에 SSE가 완벽한 선택이었습니다. 만약 반대로 채팅 앱을 만들었다면? WebSocket이 당연히 주인공이 되었겠죠.

 

이제 여러분도 SSE와 WebSocket 중 누구를 주인공으로 선택할지 결정할 수 있겠죠?  

SSE와 WebSocket, 그들은 왜 실시간 통신의 라이벌이 되었을까?

덕토피아

SSE와 WebSocket, 그들은 왜 실시간 통신의 라이벌이 되었을까?

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2024년 10월 25일 오전 11:30

 • 

저장 69조회 6,816

댓글 0