HTTP의 규격이 만들어졌을 무렵에는 주로 HTML로 작성된 문서를 전송하기 위한 프로토콜로 HTTP를 생각했었음
-> 이는 시대를 거치면서 쇼핑 사이트나, SNS, 기업이나 조직 내의 각종 관리 툴등 그 용도가 다방면에 이름
-> 하지만 HTTP라는 프로토콜의 제한이나 한계가 있기에 효율적이지 않음
-> 따라서 HTTP를 기반으로 해서 여기에 추가되는 형태로 새로운 프로토콜이 몇가지 구현 됨
HTTP의 병목 현상을 해소하고 웹 페이지 로딩 시간을 50% 단축한다는 목표를 세우고 개발 됨
SNS는 수백, 수천 만명의 유저가 메세지 등의 정보를 작성하면, 웹 사이트에 그 정보들이 추가되면서 단시간에 대량의 갱신 정보가 발생 함
-> 갱신된 정보를 빨리 실시간으로 표시하기 위해서 클라이언트가 항상 서버 측에 확인하러 가야 함
-> 현재 웹 요구되고 있는 사용하는 방법으로 하려고 한다면 HTTP의 사양이 병목 현상이 됨
다음과 같은 HTTP의 사양이 병목 현상이 됨
리스폰스만을 받는 것은 불가능
Ajax(Asynchronous JavaScript + XML)란 JavaScript나 DOM(Document Object Model)조작 등을 활용하는 방식으로, 웹 페이지의 일부분만 고쳐쓸 수 있는 비동기 통신 방법
(서버와 클라이언트 간)
-> 페이지 일부분만 갱신되기 때문에 리스폰스로 전송되는 데이터 양은 줄어든다는 장점
-> 기존 HTTP 통신의 경우 상당한 양의 페이지의 작은 부분만 업데이트 해도 전체 페이지가 다시 로드됨으로 불필요한 통신이 많음
Ajax 사용 시 javaScript 등의 스크립트 언어로 서버와 HTTP 통신을 할 수 있기 때문에
, 이를 사용함으로써 이미 읽어 들인 웹 페이지부터 리퀘스트를 발행할 수 있기 때문에 페이지의 일부 데이터만 받는 것이 가능
-> Ajax를 사용해 실시간으로 서버에서 정보를 취득하려고 하면 대량의 리퀘스트가 발생한다는 문제(또한 HTTP 프로토콜 자신이 가지고 있는 문제가 해결되는 것이 아님)
Comet은 서버 측의 콘텐츠에 갱신이 있었을 경우, 클라이언트 부터 리퀘스트를 기다리지 않고 클라이언트에 보내기 위한 방법
-> 응답을 연장시킴으로서 서버에서 통신을 개시하는 서버 푸시 기능을 유사하게 따름
-> 즉 통상 리퀘스트가 오면 리스폰스를 바로 반환하지만 Comet에서는 리스폰스를 보류 상태로 해 두고, 서버의 콘텐츠가 갱신되었을 때에 리스폰스를 반환한다는 것
콘텐츠를 실시간으로 갱신할수 있다는 장점이 있지만, 리스폰스를 보류하기 위해 커넥션을 유지하는 시간이 길어짐
-> 유지동안 리소스를 소비하게 되며, HTTP 자체의 문제가 해결된 것은 아님
Ajax와 Comet 등 사용성을 쾌적하게 하는 여러 가지 기술이 등장해서 어느 정도 개선이 되었지만, HTTP라는 프로토콜의 제약은 없앨 수 없음
-> 근본적인 개선을 위해 프로토콜 레벨에서의 개선이 필요
-> SPDY는 HTTP가 안고 있던 병목 현상을 프로토콜 레벨에서 해소하기 위해 개발이 진행되고 있는 프로토콜
SPDY는 HTTP를 완전히 바꿔 놓는 것이 아니라 TCP/IP의 애플리케이션 계층과 트랜스 포트 계층 사이에 새로운 세션 계층
으로 추가하는 형태로 동작
-> 또한 SPDY는 보안을 위해서 표준으로 SSL 사용
-> SPDY가 세션 계층으로서 그 사이에 들어감으로써 데이터의 흐름을 제어하지만, HTTP 커넥션은 확립되어 있음(메서드나 쿠키 같은것 그대로 사용 가능)
SPDY 사용시 다음과 같은 기능을 HTTP에 추가 가능
단일 TCP 접속을 통해서 복수의 HTTP 리퀘스트를 무제한으로 처리할 수 있음
-> 한번의 TCP 접속으로 리퀘스트를 주고 받는 것이 가능하기 떄문에 TCP 효율이 높아짐
SPDY는 무제한으로 리퀘스트를 병렬 처리할 수 있지만, 각 리퀘스트에 우선 순위를 할당 가능
-> 복수의 리퀘스트를 보낼 때 대역폭이 좁으면 처리가 늦어지는 현상을 해결하기 위함
리퀘스트와 리스폰스의 HTTP 헤더를 압축
-> 적은 패킷 수와 송신 바이트 수로 통신 가능
서버에서 클라이언트로 데이터를 푸쉬하는 서버 푸쉬 기능 지원
-> 서버 측에서 클라이언트의 리퀘스트를 기다리지 않고 데이터를 보낼 수 있음
서버가 클라이언트에게 리퀘스트 해야 할 리소스를 제안할 수 있음
-> 클라이언트가 이미 캐시를 가지고 있는 상태라면 불필요한 리퀘스트를 보내지 않아도 됨
SPDY를 사용하고 싶을 경우에는 웹 콘텐츠 측은 특별히 의식할 필요는 없지만, 웹 브라우저와 웹 서버는 SPDY에 대응하고 있을 필요가 있음
-> 브라우저에서 대응하고 있는 경우도 맞지만, 실제로 그다지 진행되어 있지 않음
SPDY는 기본적으로 한 개의 도메인(IP 주소)과의 통신을 다중화할 뿐이기 때문에 하나의 웹 사이트에서 복수의 도메인으로 리소스를 사용하고 있는 경우엔 효과가 한정적
Ajax와 Comet을 사용한 통신은 웹 브라우징을 가속화하지만, HTTP라는 프로토콜을 사용하고 있는 이상 병목 현상을 해결할 수 없음
-> WebSocket은 새로운 프로토콜과 API에 의해 이 문제를 해결하기 위한 기술로서 개발되어 있음
WebSocket은 웹 브라우저와 웹 서버를 위한 양방향 통신 규격
-> 주로 Ajax나 Comet에서 사용하는 XMLHttpRequest의 결점을 해결하기 위한 기술로서 개발이 진행
HTTP는 stateless 프로토콜이기 때문에, 요청에 대한 응답이 전송된 후 클라-서버 간의 연결이 닫히고 이전 상호작용에 대한 지식을 유지하지 않음
-> HTTP는 단순하고 일회성 정보 요청에 적합
반면 WebSocket은 단일 TCP 연결
을 통한 양방향 통신 프로토콜
-> 클라이언트와 서버 간에 지연 시간이 짧은 실시간 통신이 가능!
-> Web Socket에 의해 연결이 된 경우, 서버와 클라이언트 어느 쪽에서도 송신을 할 수 있게 됨
서버 푸시 기능
-> 서버는 클라이언트의 리퀘스트를 기다리지 않고 데이터를 보낼 수 있음
통신량의 삭감
-> WebSocket은 접속을 한번 확립하면 접속을 유지하려고 함
(HTTP에 비해서 자주 접속을 하는 오버헤드가 줄어들고, 헤더 사이즈가 작어 통신량을 줄일수 있음)
-> WebSocket으로 통신을 하려면 한번 HTTP에 접속을 확립하고 , Web Socket 통신을 하기 위해 handshake
절차를 밟을 필요가 있음
핸드쉐이크/리퀘스트
-> WebSocket으로 통신을 하려면 HTTP의 Upgrade 헤더 필드를 사용해서 프로토콜을 변경하는 것으로 핸드쉐이크 실시
ex)
GET /chat HTTP/1.1
Host : server.example.com
Upgrade : websocket
Connection : Upgrade
Sec-WebSocket-Key : dGhilllsdkjzxkl123==
Origin : http:example.com
Sec-WebSocket-Protocol : chat, superchat
Sec-WebSocket-Version : 13
Sec-WebSocket-Key에는 핸드쉐이크에 필요한 키가 저장되어 Set-WebSocket-Protocol에는 사용하는 서브 프로토콜이 저장되어 있음
핸드쉐이크/리스폰스
-> 일반 리퀘스트에 대한 리스폰스는 상태 코드 [101 Switching Protocols]로 반환
HTTP/1.1 101 Switching Protocols
Upgrade : websocket
Connection : Upgrade
Sec-WebSocket-Accept : ~~~
Sec-WebSocket-Protocol : chat
위와 같이 핸드쉐이크에 의해 WebSocket 커넥션이 확립된 후에는 HTTP가 아닌, WebSocket의 독자적인 데이터 프레임을 이용해 통신을 진행
WebSocket API를 사용해서 50ms에 1번 데이터를 송신하는 예시
var socket = new WebSocket('ws://game.example.com:12010/updates');
socket.onopen = function(){
setInterval(function(){
if(socket.bufferedAmount == 0)
socket.send(getUpdateData());
}, 50);
};
HTTP/2.0은 사용자가 웹을 이용할 때의 체감 속도 개선을 목표로 함
-> HTTP/1.1 경유로 TCP를 사용하는 것이 기본으로 되어 있기 때문에 다음의 프로토콜이 베이스가 되어 사양이 검토되고 있음
HTTP/ 1.1 과의 차이점
바이너리 형식
: 1.1에서 사용되는 텍스트 기반 형식 대신 2.0은 바이너리 형식을 사용하므로 효율적인 인코딩과 빠른 데이터 전송이 가능
멀티플렉싱
: 단일 연결을 통해 여러 요청과 응답을 동시에 보낼수 있으므로 대기 시간이 줄고 전반적인 전송 속도가 향상
서버 푸쉬
: 클라이언트가 리소스를 요청할 때 까지 기다리지 않고 서버가 사전에 리소스를 클라이언트에게 보낼 수 있음
헤더 압축
: 헤더와 전송해야 하는 데이터 양을 효율적인 압축 알고리즘으로 줄임
우선 순위 지정
: 클라이언트가 다양한 요청의 우선 순위를 나타낼 수 있도록 할 수 있음(중요한 리소스가 먼저 전송되도록)
WebDAV(Web-based Distributed Authoring and Versioning)
는 웹 서버의 콘텐츠
에 대해서, 직접 파일 복사나 편집 작업
등을 할 수 있는 분산 파일 시스템으로, HTTP/1.1을 확장한 프로토콜
파일 작성이나 삭제 등 기본적인 기능 이외에 파일 작성자 등의 관리나 편집 중에 다른 유저가 다시 고쳐 쓰지 못하도록 잠금 기능
, 갱신 정보를 관리하는 리비전 기능
등이 준비되어 있음
-> HTTP/1.1의 PUT 메서드나 DELETE 메서드를 사용하면 웹 서버 상의 파일 작성이나 삭제 등을 할 수 있지만 보안이나 편의성 문제로 인해 사용하지 않음
Collection
: 여러 개의 리소스를 한꺼번에 관리하기 위한 개념(각종 조작을 보통 컬렉션 단위로 진행)
Resource
: 파일이나 컬렉션을 리소스라 부름
Property
: 리소스의 프로퍼티를 정의한 것(이름 = 값)
Lock
: 파일을 편집할 수 없는 상태로 함(여러 명의 사람이 동시에 편집하는 경우 등 동시에 작성되는 걸 예방)
PROPFIND : 프로퍼티 취득
PROPPATCH : 프로퍼티 변경
MKCOL : 컬렉션 작성
COPY : 리소스 및 프로퍼티 복제
MOVE : 리소스 이동
LOCK : 리소스 잠금
UNLOCK : 리소스 잠금 해제
102 Processing : 리퀘스트는 정상적으로 수신되었지만 아직 처리중이다
207 Multi-STatus : 복수의 스테이터스를 가지고 있다
422 Unprocessable Entity : 서식은 올바르지만 내용이 틀리다.
423 Locked : 리소스가 잠겨 있다
424 Failed Dependency : 어떤 리퀘스트와 관련된 리퀘스트가 실패했기 때문에 의존 관계를 유지하지 못한다
507 Insufficient Storage : 기억 영역이 부족하다
PROPFIND /example.txt HTTP/1.1
Host: www.example.com
Depth: 1
HTTP/1.1 207 Multi-Status
Date: Mon, 15 Jan 2018 12:00:00 GMT
Content-Type: application/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response>
<D:href>http://www.example.com/example.txt</D:href>
<D:propstat>
<D:prop>
<D:getlastmodified>Mon, 15 Jan 2018 12:00:00 GMT</D:getlastmodified>
<D:getcontentlength>12345</D:getcontentlength>
<D:getcontenttype>text/plain</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>