이제 드디어 WebSocket에 대한 이야기를 해보려고 한다.
앞서 살펴봤듯이, HTML, AJAX 등 아무리해도 해결못하는 고질적인 문제가 하나 있었다. 바로
이런 상황에서 양쪽 모두가 통신을 주고받을 수 있는 규약이 만들어졌는데, 이것이 바로 양방향 통신 프로토콜, 웹소켓(WebSocket)이다.
HTTP와 같은 통신 프로토콜으로, 양방향 통신이라는 것 빼고는 모두 동일하다.
(API는 W3C에서 관장하고, 프로토콜은 IETF에서 관장한다고 한다)
HTTP와 마찬가지로 IP와 PORT(80)로 통신을 하며, Upgrade 헤더를 통해 웹서버에 요청을 한다.
GET /... HTTP/1.1
Upgrade: WebSocket
Connection: Upgrade
모든 통신에는 핸드셰이킹(연결) 과정이 있다. 웹소켓 또한 마찬가지.
WebSocket 패킷을 덤프 떠보면 다음과 같이 주고 받는다.
(직접적인 관련이 없는 부분은 생략)
// 요청 패킷
GET / HTTP 1.1
Host: /* 페이지의 호스트 주소(+포트) */
Connection: Upgrade
Upgrade: websocket
Origin: /*요청한 페이지(클라이언트) 주소*/
Sec-WebSocket-Key: /* 연결을 위한 키 값 */
// 응답 패킷
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: /* 연결 키 값 */
WebSocket-Origin: /* 요청한 클라이언트의 주소 */
WebSocket-Location: ws://(페이지의 호스트 주소)/
뭔가 많지만, 사실 내용은 간단하다.
모두 살펴보진 않고, 중요 부분만을 살펴볼 것이다.
우선 요청 패킷부터 알아보자.
1. Upgrade
: 이미 설정된 커넥션을 다른 프로토콜로 업그레이드할 때 사용한다.
(HTTP/2.0으로 바꿈, WebSocket으로 바꿈 등)
2. Sec-WebSocket-Key
: 모든 연결은 커넥션을 맺기 전에 서로를 인증한다.
이런 인증을 하기 위해 클라이언트가 제공하는 임의의 키이다.
이번엔 응답 패킷을 살펴보자.
1. 101 상태 코드
: Switching Protocols라고 한다. Upgrade로 프로토콜을 바꿀 때 사용하는 상태 코드이다.
2. Sec-WebSocket-Accept
: 클라이언트의 키 값으로 서버가 계산한 키.
이 값이 올바르지 않다면 클라이언트는 잘못된 연결로 인식하고, 연결을 끊어버린다.
간단한 코드를 구현해 보도록 하자.
if ('WebSocket' in window) {
// 소켓 연결
var webSock = new WebSocket(“ws://localhost:80”);
// 메시지 송신
webSock.send(“message”);
// 메시지 수신
var recvData = e.data;
console.log(recvData);
// 웹소켓 종료
webSock.close();
}
정말 초간단 압축하여 작성해 보았다.
실제 과정은 복잡하지만, 코드는 누구나 이해할 수 있는 코드이다.
조금 생소한 것이 ws://~~일텐데, ws는 websocket의 약자로 ~~주소로 WebSocket 통신하겠다는 의미이다.
이제야 간단한 웹소켓에 대해 알아보았다.
다음 시간에는 웹소켓을 스프링으로 알아보는 시간을 가져보도록 한다!