?️ 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 중 누구를 주인공으로 선택할지 결정할 수 있겠죠?
좋아요 47 • 저장 69