웹 소켓을 HTML5에서 새로 추가되었고 실시간 양방향 데이터 전송을 위해 만들어졌다. 웹소켓은 WS프로토콜을 사용하고 대부분의 최신 브라우저는 이를 지원한다. 노드에서 WS를 사용하는 대표적인 방법은 ws 또는 Socket.IO 패키지를 사용하는 것이다. 이 방식을 사용하면 한번의 연결 후 지속적으로 연결이 유지되서 업데이트가 발생하면 서버가 자동으로 클라이언트에게 알린다. 또 한 HTTP와 포트를 공유한다.
Polling
웹 소켓이 나오기 이전에 실시간 데이터 전송을 위해 사용했던 방법이다. 이는 HTTP가 클라이언트->서버형태의 통신이므로 주기적으로 서버에 업데이트가 있는지 확인을 하고 있다면 반환하는 방식이다.
Server Sent Events(SSE)
이 기술은 EventSource라는 객체를 사용하고 웹소켓처럼 한번의 연결를 지속적으로 유지한다. 하지만 SSE는 오직 서버에서 클라이언트로 데이터를 보낼 수 있는 단방향 통신이다.
ws 사용
아래 링크는 ws 사용에 대한 간단한 예제이다.
클라이언트가 localhost:8080에 접속하면 socket.js에서 해당 메시지를 처리한다.3초에 한번 메시지를 보내게 설정을 해놨기 때문에 클라이언트 콘솔에서 3초에 한번 서버로부터 메시지를 받는것을 확인할 수 있다.
클라이언트에서 종료를 하면 socket.js에서 연결 해제와 관련된 부분에서 연결 해제 메시지가 출력되는 것을 볼 수 있다.
ws 예제 소스코드:github.com/skullkim/web-socket-with-express/tree/main/ws_practice
socket.io 사용
socket.io는 서버로 보낼 메시지, 클라이언트로 보낼 메시지에 대해 각각 이벤트를 하나씩 정의해줘야한다. 이때의 이벤트는 'click'이나 'loading'처럼 정의된 이벤트가 아닌 사용자 정의 이벤트이다. 예를들어 클라이언트에서 서버로 메시지를 보내고 싶은 경우 socket.emit('a', 'hello');를 사용하면 a는 이벤트, hello는 보내고 싶은 메시지가 되는데. 이때 이 메시지를 서버에서 받기 위해서는 서버에 socket.on('a', (message) => {....})가 존재해야한다. 여기서 message는 서버가 받은 메시지가 된다(hello).
이 예제에서는 'reply'와 'news' 두개의 이벤트를 사용했다. 'reply'의 경우 클라이언트에서 서버로 보내는 메시지의 이벤트이고, 'news'는 서버에서 클라이언트로 보내는 메시지이다.
클라이언트 측에서에 <script src="/socket.io/socket.io.js"></script>를 사용하는데 이는 Socket.IO에서 제공하는 스크립트이고 실제 파일이 아니다.
socket.io는 HTTP를 사용한다. 즉, 폴링방식을 사용한다. 폴링으로 연결을 하고 만약 브라우저가 웹 소켓을 지원한다면 웹소켓 방식으로, 지원하지 않는다면 폴링방식을 사용한다. 만약 무조건 웹 소켓 만을 사용하고 싶다면 io.connect()의 두번째 인자에
transports: ['websocket']를 사용하면 된다.
전체 소스코드:github.com/skullkim/web-socket-with-express/tree/main/socketio