Socket.io - 42-Tomodachi/ft_transcendence GitHub Wiki

socket.io가 뭔가요?

socket.io란 실시간 양방향 서비스를 구현하기 위한 Javascript 모듈입니다.

HTTP의 한계

HTTP프토콜을 이용한 통신은 단방향 통신입니다.

클라이언트가 서버에게 정보를 요청하면 → 서버가 이에 응답하는 방식으로 통신합니다.

서버측에 어떠한 변경이 일어나도 클라이언트가 다시 정보를 요청하기 전까지 이는 클라이언트 측에 반영되지 않습니다.

그렇기에 영화 예매 사이트나 실시간 채팅 등의 서비스를 구현하는데 HTTP프로토콜의 통신방식은 적합하지 않습니다.

HTTP통신을 이용하는 브라우저와 웹서버간의 통신에서 실시간 서비스를 구현하기 위해

많은 방법들이 등장했습니다.

실시간 서비스를 위해 등장한 기술들

실시간 서비스를 구현하기 위해 등장한 첫번째 기술은 polling입니다.

polling은 클라이언트가 서버에 일정 시간 간격으로 반복하여 서버에 요청을 보내어 변경사항을 업데이트 하는 방식입니다.

(일정 간격으로 계속해서 새로고침을 한다고 보면 될 것 같습니다.)

서버에 보내는 요청의 주기를 짧게 할수록 실시간 서비스에 가까워지지만

그만큼 잦은 요청에 의해 서버가 받는 부하가 커지기에

요청 주기를 진정한 실시간 서비스를 구현할 정도로 짧게 하기에는 무리가 있다고 볼 수 있습니다.

이러한 polling의 한계를 극복하기 위해 나온 기술이 long polling입니다.

long polling과 polling은 클라이언트가 지속적으로 서버에 요청을 보낸다는 것은 동일하지만

long polling 요청을 받은 서버는 클라이언트에게 즉시 응답하는 것이 아니라

서버 측에 클라이언트에게 알려야 하는 변경사항이 생길 경우에만 클라이언트에 응답하도록 코드를 작성하는 방법입니다.

만약 응답할 것이 없다면 일정 시간이 지나면 timeout 메세지를 클라이언트에게 응답하며

timeout 응답을 받은 클라이언트는 곧바로 다시 long polling 요청을 서버에게 보냅니다.

클라이언트는 지속적으로 서버에 요청을 보내지만 서버는 변경사항이 발생할 경우에만(혹은 일정 시간이 지나 timeout이 발생한 경우에도) 클라이언트에 이를 응답하여

잦은 응답으로 서버에 부하를 주지 않고 실시간 서비스를 구현할 수 있지만

여전히 불필요한 요청과 응답에 관한 오버헤드가 존재하고 서버가 클라이언트 측의 요청에 의해 응답하는 방식이므로

양방향 통신이라 부르기에는 무리가 있습니다.

polling과 long polling처럼 클라이언트 측에서 서버에 주기적으로 요청을 보내어

변경사항을 응답받는 방식을클라이언트 폴링 방식이라고 부릅니다.

WebSocket기술이 등장하기 이전에는 웹 실시간 통신에 클라이언트 폴링 방식을 사용했습니다. (잘 알려진 ajax와 streaming등의 기술도 클라이언트 폴링 방식을 사용합니다.)

이와 반대로 서버측에서 변경사항 발생 시 클라이언트의 요청이 없더라도 먼저 메세지를 보내는 방식을

서버 푸쉬 방식이라고 부릅니다.

소켓, 진정한 의미의 실시간 통신

유닉스, 리눅스 계열의 운영체제에는 소켓이라는 개념이 있어

서버와 클라이언트가 소켓을 이용하여 실시간 양방향 통신을 할 수 있습니다.

서버와 클라이언트는 각자 소켓이라는 것을 갖고 있으며

두 소켓은 연결을 맺은 후에 각자의 소켓에 데이터를 입,출력하여

상대방 소켓에 데이터를 보내고 나의 소켓으로부터 데이터를 가져올 수 있습니다.

서버가 자신의 소켓에 데이터를 입력하면 곧바로 클라이언트에게 전달됩니다.

클아이언트가 자신의 소켓에 데이터를 입력하면 곧바로 서버에게 전달됩니다.

소켓을 이용하면 서버 푸쉬 방식의 실시간 양방향 서비스를 구현할 수 있습니다.

socket.io의 역할

본래 socket.io는 웹에서 소켓처럼 실시간 서비스를 구현하는 모듈이라는 뜻에서

socket.io라는 이름이 붙여졌습니다.

과거에는 다양한 실시간 통신 기술이 있었으나

브라우저마다 지원하는 기술들이 각자 달랐기에 (과거에는 브라우저마다 내장된 javascript 해석기가 다 다르고 이에 대한 표준이 명확하지 않아 그랬을거라고 추정)

어떤 브라우저는 서버와 통신할 때 polling 방식만 사용 가능하고

어떤 브라우저는 polling과 long lolling 모두 사용 가능하다고 했을 때

서버측에서 socket.io를 이용할 시 이와 통신하는 클라이언트 중

polling이 사용가능한 브라우저에서는 polling방식을 이용하여 서버와 통신하도록 해주며

long polling이 사용가능한 브라우저에서는 long polling방식을 이용하여 서버와 통신하도록 해주는 등

서버측에서 클라이언트의 브라우저 환경에 관계없이 일관된 코드로 실시간 통신을 할 수 있는 환경을 제공해 주는 것이

socket.io의 역할입니다.

WebSocket의 등장

2008년에 HTML5 라는 표준이 등장합니다.

주류 브라우저 회사들은 (MS, Google, Apple, Mozilla 등…)

WHATWG라는 단체를 만들어 브라우저들의 일관적인 HTML해석과 그를 위한 HTML양식의 표준을 제정합니다.

이제 브라우저의 다양성에 고통받던 웹 개발자들은

HTML5 표준을 준수하는 웹 브라우저들을 대상으로 마음놓고 일관된 코드를 작성할 수 있게 되었습니다.

이 때 HTML5의 표준에 등장한 기술 중 하나가 WebSocket입니다.

WebSocket은 웹에서 서버와 클라이언트간의 소켓 통신을 구현한 것으로서

HTTP통신과 80번 포트를 이용하여 서버와 클라이언트는 소켓 연결을 맺은 후

이후 서버와 클라이언트가 연결된 소켓을 이용하여 실시간으로 이벤트(메세지)를 주고받을 수 있도록 구현한 기술입니다.

WebSocket의 등장 이후 웹에서 서버와 클라이언트간에 소켓을 이용한 진정한 의미의 실시간 양방향 통신이 가능해졌으며

socket.io에서도 이를 지원하여 socket.io를 사용할 시

그동안의 클라이언트 풀링 방식과 더불어 WebSocket방식이 사용 가능한 브라우저는 이를 이용하여 서버와 통신하도록 하게 되었습니다.

지금은 대부분의 브라우저가 WebSocket 통신이 사용 가능하므로

socket.io를 사용하면 대부분의 클라이언트가 내부적으로는 WebSocket기능을 통해 서버와 통신한다고 볼 수 있으며

WebSocket 연결이 실패할 시 long polling방식으로 연결을 시도하는 등의 방법으로 socket.io 가 동작하고 있습니다.

WebSocket이 있음에도 여전히 Socket.io를 사용하는 이유

WebSocket 모듈에는 서버와 클라이언트간의 소켓 연결과 이를 이용한 통신기능만 존재합니다.

WebSocket을 이용하여

서버측에서 연결된 클라이언트 중 일부의 클라이언트에게만 메세지를 보낸다던지,

연결된 모두의 클라이언트들에게 메세지를 보낸다던지 등의 기능을 구현하려면

직접 해당 로직을 작성해야합니다.

하지만 socket.io에는 NameSpace, rooms등의 기능이 있어서 이를 이용하면

로직 작성 없이도 언급한 기능들을 편리하게 사용할 수 있습니다.