본문 바로가기

Develop/Frontend 가이드

[FE] Web API - WebSocket API

반응형

WebSocket API
WebSocket API

Web API - WebSocket API

HTTP/1.1 프로토콜은 클라이언트가 TCP 프로토콜로 서버와 연결한 뒤에 요청을 보내고 서버로부터 응답을 받고 나면 연결을 해제하는 프로토콜입니다. 클라이언트가 요청을 보내지 않으면 서버와 연결되지 않기 때문에 서버가 주도적으로 클라이언트와 통신을 시작할 수 없습니다. 그래서 서버가 클라이언트에게 무엇인가 알려주고 싶어도 방법이 없습니다. 서버 내부적인 변경을 감지할 수 없는 클라이언트가 서버가 원하는 걸 눈치채고 요청을 보내는건 불가능합니다. 그래도 이를 해결하고자 여러 방법이 시도되었습니다.

먼저, 클라이언트가 일정 주기로 서버에게 변경사항이 있는지 확인하는 방법이 제일 직관적이고 구현이 간단합니다. 하지만, 이 방법은 현업에서 사용될 수 없는 방법입니다. 왜냐하면 변경이 없더라도 계속 서버에게 요청을 보내야 하는 비효율 문제도 있고, 많은 클라이언트가 운 좋게 동일한 순간에 요청을 보내면 일순간 서버에게 과한 부담을 주게 되어 서버가 대응하지 못하고 죽는 문제가 발생할 수 있습니다. 그리고 일정 주기로 동기화하는 거라 반드시 지연이 발생하게 됩니다. 그래서 거의 사용하지 않습니다.

그나마 어느 정도 운용 가능한 방법은 Long polling 입니다. Polling 이란 서버로부터 데이터를 끌어 당기는 행위인데, Long polling 은 서버가 클라이언트가 보낸 요청에 바로 응답하지 않아서 연결을 유지하는 방법입니다. HTTP/1.1 프로토콜은 응답을 받으면 연결을 해제하기 때문에, 응답을 하지 않는 편법으로 TCP 연결을 유지합니다. 그러다 서버가 클라이언트에게 알려주고 싶은 사항이 생기면 응답을 보냅니다. 클라이언트는 서버로부터 응답이 도착하면 일단 연결은 끊어지고, 다시 요청을 보내서 서버가 요청을 붙잡고 대기할 수 있도록 합니다. 이 방법도 단점이 치명적이라 사용하기 부담스럽습니다. 먼저 TCP 연결을 유지하기 위한 비용이 상당합니다. 일반적으로 서버는 요청 하나에 쓰레드 하나를 만들어 처리하는 방식으로 동작하는데, 클라이언트와의 연결을 유지하기 위해 서버가 불필요하게 많은 쓰레드를 만들고 관리해야 하는 부담이 발생합니다.

서버가 클라이언트에게 데이터를 전달하고 싶은 수요를 해결하기 위해 등장한 API 가 WebSocket API 입니다. WebSocket 은 TCP 연결로 서버가 클라이언트에게 데이터를 보내고 받는 양방향 통신이 가능하도록 하는 프로토콜입니다. 클라이언트는 아래와 같은 코드로 WebSocket 객체를 생성할 수 있습니다.

// WebSocket(url[, protocols])
var exampleSocket = new WebSocket("wss://www.example.com/socketserver", "customProtocol");

WebSocket 은 HTTP 프로토콜이 아니기 때문에 WebSocket 의 URL 은 https 가 아닌 wss 로 시작합니다. URL 다음에 WebSocket 으로 어떤 프로토콜을 바탕으로 통신할지를 전달합니다. 서버와의 연결이 무사히 이루어지면 exampleSocket.readyState 프로퍼티가 OPEN 이 됩니다.

exampleSocket.onopen = function (event) {
  //  readState 가 OPEN 이 되어 WebSocket 이 연결될 때
};

WebSocket 으로 데이터를 주고 받는건 아래와 같이 하면 됩니다.

// 서버에게 WebSocket 으로 데이터는 아래와 같이 전달할 수 있다.
exampleSocket.send(JSON.stringify(msg));

exampleSocket.onmessage = function (event) {
  // 서버로부터 응답은 여기서 받으면 된다.
  var msg = JSON.parse(event.data);
  console.log(msg);
}

WebSocket 연결은 close() 메서드를 호출해서 끊을 수 있습니다.

exampleSocket.close();

WebSocket 서버

WebSocket 은 HTTP 프로토콜을 사용하지 않기 때문에 서버가 WebSocket 연결을 받고 처리하는 과정을 따로 구현해야 합니다. 이 부분은 각 서버 프레임워크마다 구현하는 방법이 상이할 수는 있지만, 기본적으로 TCP 통신을 처리하는 것과 동일하기 때문에 프레임워크가 많은 부분을 도와줍니다. 특히 C# 의 ASP.NET Core 의 경우, SignalR 라이브러리로 지원해주기 때문에 문서만 잘 읽고 따라하기만 하면 구현하기 어렵지 않습니다.

반응형