본문 바로가기
Backend

웹소켓과 서버센트

by Yunny52 2023. 5. 30.

새로운 프로젝트에서 채팅 기능을 구현에 도전한다!

웹소켓과 서버센트, 둘 중 어떤 걸 선택해야 할까?

 

 

📌 웹소켓 (Web Socket)

 

#️⃣ 웹소켓이란?

HTML5 표준 기술로, HTTP 환경에서 하나의 TCP 연결을 통해 실시간으로 서버와 클라이언트 간의 양방향 통신(전이중 통신)을 가능하게 하는 기술이다. 즉, 웹소켓을 이용하면 하나의 HTTP 접속으로 양방향 메시지를 자유롭게 주고 받을 수 있다.

 

웹소켓이 나오기 이전에는 클라이언트의 요청이 없다면 서버로부터 응답을 받을 수 없는 구조였다.

웹소켓에서는 서버와 브라우저 사이의 양방향 통신이 가능하므로, 브라우저는 서버가 직접 보내는 데이터를 받아들일 수 있고 사용자가 다른 웹사이트로 이동하지 않아도 최신 데이터가 적용된 웹을 볼 수 있게 해준다.

 

#️⃣ 웹소켓 동작 방식

웹소켓은 전이중 통신이므로, 연속적인 데이터 전송의 신뢰성을 보장하기 위해 Handshake 과정을 진행한다.

기존의 다른 TCP 기반의 프로토콜은 TCP layer에서의 Handshake를 통해 연결을 수립하는 반면, 웹소켓은 HTTP 요청을 기반으로 Handshake을 통해 연결을 수립한다.

 

웹소켓은 연결을 수립하기 위해 Upgrade 헤더와 Connection 헤더를 포함하는 HTTP 요청을 보낸다.

통상적인 상태 코드 200 대신, 웹소켓 서버의 응답은 다음과 같다.

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-Websocket-Accept: qwieojeidkeiorfeijo=
Sec-Websocket-Protocol: v10.stomp
  • 101 Switching Protocols: Handshake 요청 내용을 기반으로 다음부터 웹소켓으로 통신할 수 있다.
  • Sec-WebSocket-Accept: 보안을 위한 응답키

 

Handshake 과정을 통해 연결이 수립되면, Application 계층 프로토콜이 HTTP에서 웹소켓으로 업그레이드 된다.

이후엔 HTTP는 사용되지 않고, 웹소켓 연결이 닫힐 때까지 두 끝점에서 웹소켓 프로토콜을 사용하여 데이터를 주고 받게 된다. 웹소켓 연결은 주로 새로고침이나 창닫기 등의 이벤트 발생 시 닫힌다.

 

#️⃣ 웹소켓 vs HTTP

웹소켓이 HTTP 요청으로 시작되며 HTTP에서 동작하지만, 두 프로토콜은 분명히 다르게 동작한다.

  • HTTP는 클라이언트와 서버 간 접속을 유지하지 않으며 요청과 응답 형태로 단방향 통신만 가능하다. 따라서 서버에서 클라이언트로의 요청은 불가능하다. 또한 요청-응답이 완료되면 수립했던 연결이 닫힌다. 하지만 웹소켓은 클라이언트와 서버 간 접속이 유지되며 요청과 응답 개념이 아닌 서로 데이터를 주고 받는 형식이다.
  • REST한 방식의 HTTP 통신에서는 많은 URI와 HTTP Method를 통해 웹 어플리케이션과 상호작용하지만, 웹소켓은 초기 연결 수립을 위한 오직 하나의 URL만 존재하며, 모든 메시지는 초기에 연결된 TCP 연결로만 통신한다.

 


📌 서버센트 (Server-Sent-Event)

 

#️⃣ 서버센트란?

서버에서 클라이언트로 데이터를 실시간으로, 지속적으로 streaming 하는 기술이며, 웹 표준으로써 IE를 제외한 모든 브라우저에서 지원되며, IE 역시 polyfill을 통해 지원 가능하다.

서버와 클라이언트 사이에 단일 단방향 채널을 연다.

 

서버센트는 기존 HTTP 웹 서버에서 HTTP API 만으로 동작되며 구현도 간단하기 때문에 서버와 프론트엔드 양측 모두 쉽게 개발이 가능하다. 

 

#️⃣ 서버센트 동작 방식

서버센트는 파일 전송처럼 첫 연결 시에 데이터를 주고 받은 뒤 연결된 상태를 유지하고 서버가 일방적으로 데이터를 전송한다.

 

서버센트는 기존의 웹 서버 동작 방식인 HTTP를 그대로 사용하기 때문에 서버 쪽에서는 서버센트를 사용하겠다는 헤더만 설정한 뒤 데이터를 보내기만 하면 된다.

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SSEServlet extends HttpServlet {

	public void subscribe(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	
		response.setContentType("text/event-stream"); // Header에 Content Type을 Event Stream으로 설정
		response.setCharacterEncoding("UTF-8");       // Header에 encoding을 UTF-8로 설정

		PrintWriter writer = response.getWriter();
		for(int i = 1; i <= 10; i++) {
			writer.write("data: { \"message\" : \"number : "+ i + "\" }\n\n");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		writer.close();
	}
}

여기서 주의해야 할점은 헤더에 Content Type을 "text/event-stream"으로, encoding을 UTF-8로 설정 해야 한다는 점이다. 헤더를 설정한 이후에는 데이터를 전송하고, 데이터를 전송할때는 "data:" prefix를 붙여야 하며 line break(\n) 두 개를 끝에 추가해 주어야 한다.

 

이렇게 구현한 코드는 아래와 같이 데이터를 전송한다.

...
data: { "message" : "number : 1" } \n\n
data: { "message" : "number : 2" } \n\n
data: { "message" : "number : 3" } \n\n
data: { "message" : "number : 4" } \n\n
...

 


📌 웹소켓과 서버센트(Server-Sent-Event)의 차이점

웹소켓과 서버센트의 가장 큰 차이점은 통신방향이다. 웹소켓을 이용하면 양방향으로 데이터를 주고받을 수 있지만 서버센트를 이용하면 단방향이므로 클라이언트는 데이터를 받을 수만 있게 된다. 어느 것이 더 유리하다고는 할 수 없다. 실시간 채팅처럼 클라이언트와 서버가 양방향으로 데이터를 주고 받는 경우에는 웹소켓이 더 적합하지만, 서버센트는 별도 서버가 필요 없다는 점, 간단한 API를 제공하고 구현이 간단하다는 장점이 있기에 어떤 기능이 필요한 지에 따라서 사용할 기술을 선택하면 된다!

 

 

  웹소켓 서버센트
브라우저 지원 대부분 브라우저에서 지원 대부분 모던 브라우저 지원 (polyfills 가능)
통신 방향 양방향 단방향 (서버에서 클라이언트로)
리얼 타임 Yes Yes
데이터 형태 Binary, UTF-8 UTF-8
자동 재접속 No Yes (3초마다 재시도)
최대 동시 접속 수 브라우저 연결 한도는 없지만 서버 셋업에 따라 다름 HTTP를 통해서는 브라우저당 6개까지 가능 / HTTP2로는 100개가 기본
프로토콜 websocket HTTP
배터리 소모량 작음
Firewall 친화적 No Yes

 

 

 

'Backend' 카테고리의 다른 글

Spring Security  (0) 2023.08.07
사용자 인증 방식 | HTTP 쿠키 ▫️ Session ▫️ JWT  (0) 2023.07.24
@MappedSuperclass  (0) 2023.06.30

댓글