HTTP / 2 프로토콜에 대해 배우고 있습니다. 작은 메시지 프레임이있는 이진 프로토콜입니다. 단일 TCP 연결을 통한 스트림 멀티플렉싱이 가능합니다. 개념적으로 WebSockets와 매우 유사합니다.
더 이상 사용되지 않는 웹 소켓을 헤더가없는 HTTP / 2 요청 및 서버 시작 푸시 메시지로 대체 할 계획이 있습니까? 아니면 WebSocket이 HTTP / 2를 보완합니까?
HTTP / 2 프로토콜에 대해 배우고 있습니다. 작은 메시지 프레임이있는 이진 프로토콜입니다. 단일 TCP 연결을 통한 스트림 멀티플렉싱이 가능합니다. 개념적으로 WebSockets와 매우 유사합니다.
더 이상 사용되지 않는 웹 소켓을 헤더가없는 HTTP / 2 요청 및 서버 시작 푸시 메시지로 대체 할 계획이 있습니까? 아니면 WebSocket이 HTTP / 2를 보완합니까?
답변:
내가 이해 한 바에 따르면 HTTP / 2는 웹 소켓을 대체하는 것이 아니라 SPDY 프로토콜을 표준화하는 것입니다.
HTTP / 2에서는 server-push가 뒤에서 사용되어 브라우저에서 클라이언트의 리소스로드를 향상시킵니다. 개발자는 개발 중에 실제로 신경 쓰지 않습니다. 그러나 Websocket을 사용하면 개발자는 고유 한 전이중 연결로 메시지를 사용하고 푸시 할 수있는 API를 사용할 수 있습니다.
이것들은 같은 것이 아니며 서로 보완해야합니다.
HTTP / 2 spec을 읽은 후에 는 HTTP / 2가 대부분의 사용 사례에서 더 이상 사용되지 않는 웹 소켓을 사용한다고 생각하지만 전부는 아닙니다.
PUSH_PROMISE
(구체적으로 서버 푸시라고 함)는 여기서 문제가되지 않습니다. 그것은 단지 성능 최적화 일뿐입니다.
브라우저에서 웹 소켓의 주요 사용 사례는 데이터의 양방향 스트리밍을 가능하게하는 것입니다. 따라서 OP의 질문은 HTTP / 2가 브라우저에서 양방향 스트리밍을 활성화하는 데 더 나은 작업인지 여부가된다고 생각합니다. 그렇습니다.
우선, 그것은 이다 양방향 디. 스트림 섹션 소개를 읽으십시오 .
"스트림"은 HTTP / 2 연결 내에서 클라이언트와 서버간에 교환되는 독립적 인 양방향 프레임 시퀀스입니다. 스트림에는 몇 가지 중요한 특성이 있습니다.
단일 HTTP / 2 연결은 여러 스트림에서 엔드 포인트 인터리빙 프레임을 사용하여 동시에 여러 개의 열린 스트림을 포함 할 수 있습니다.
스트림은 일방적으로 설정 및 사용되거나 클라이언트 또는 서버가 공유 할 수 있습니다.
스트림은 양쪽 끝점으로 닫을 수 있습니다.
같은 제품 이 (다른 답변에 연결)은 HTTP / 2의 이러한 측면에 대해 잘못이다. 그들은 그것이 bidi가 아니라고 말합니다. HTTP / 2에서는 불가능한 일이 있습니다. 연결이 열리면 서버는 일반 스트림을 시작할 수없고 푸시 스트림 만 시작할 수 있습니다. 그러나 클라이언트가 요청을 전송하여 스트림을 열면 양측은 언제든지 완전한 소켓으로 영구 소켓을 통해 DATA 프레임을 전송할 수 있습니다.
이는 웹 소켓과 크게 다르지 않습니다. 서버가 데이터를 전송하기 전에 클라이언트가 웹 소켓 업그레이드 요청을 시작해야합니다.
가장 큰 차이점은 웹 소켓과 달리 HTTP / 2는 자체 멀티플렉싱 시맨틱을 정의한다는 것입니다. HTTP / 2는 또한 스트림 우선 순위 지정을위한 흐름 제어 시맨틱을 정의합니다. 이것은 대부분의 실제 bidi 응용 프로그램에서 중요합니다.
(이 잘못된 기사는 Websocket 표준에 멀티플렉싱이 있다고 말합니다. 아니요, 그렇지 않습니다. 실제로 찾기가 어렵지 않습니다. Websocket RFC 6455를 열고 ⌘-F를 누르고 "multiplex"를 입력하십시오.
프로토콜은 확장 가능하도록 고안되었습니다. 향후 버전에서는 멀티플렉싱과 같은 추가 개념이 도입 될 수 있습니다.
Websocket 멀티플렉싱을위한 2013 년 초안 확장이 있음 을 알 수 있습니다. 그러나 어떤 브라우저가 해당 브라우저를 지원하는지 모르겠습니다. 해당 확장의 뒷면에 SPA 웹 응용 프로그램을 만들려고하지 않습니다. 특히 HTTP / 2가 지원되면 지원이 도착하지 않을 수 있습니다.
멀티플렉싱은 반응 형으로 업데이트되는 단일 페이지 앱에 전원을 공급하기 위해 bidi를위한 웹 소켓을 열 때마다 일반적으로해야하는 일입니다. HTTP / 2 사양에있어서 다행입니다.
HTTP / 2가 무엇을 할 수 있는지 알고 싶다면 gRPC를보십시오. gRPC는 HTTP / 2에서 구현됩니다. gRPC가 제공하는 반이중 및 전이중 스트리밍 옵션을 구체적으로 살펴보십시오. (gRPC는 현재 브라우저에서 작동하지 않지만 실제로는 브라우저가 (1) HTTP / 2 프레임을 클라이언트 자바 스크립트에 노출하지 않고 (2) 일반적으로 트레일러를 지원하지 않기 때문에 사용됩니다. gRPC 사양)
웹 소켓은 여전히 어디에 있습니까? 가장 큰 것은 서버-> 브라우저 푸시 이진 데이터입니다. HTTP / 2는 서버-> 브라우저 푸시 이진 데이터를 허용하지만 브라우저 JS에는 노출되지 않습니다. 오디오 및 비디오 프레임 푸시와 같은 응용 프로그램의 경우 웹 소켓을 사용해야합니다.
편집 : 2020 년 1 월 17 일
시간이 지남에 따라이 답변은 점차 최상위로 올라갔습니다 (이 답변은 다소 정확하기 때문에 좋습니다). 그러나 여전히 여러 가지 이유로 정확하지 않다는 의견이 있습니다. 일반적으로 PUSH_PROMISE
단일 페이지 앱에서 메시지 지향 서버-> 클라이언트 푸시를 실제로 소비하는 방법에 대한 혼란 이나 방법 과 관련이 있습니다. 또한 브라우저에서 웹 소켓에 대한 사용 사례가 있으며 서버 푸시 바이너리 데이터입니다. JSON을 포함한 텍스트 데이터의 경우 웹 소켓을 사용하지 말고 SSE를 사용하십시오.
요약하자면, HTTP / 2 프로토콜은 완전 양방향입니다. 그러나 최신 웹 브라우저는 프레임 지향 HTTP / 2 프로토콜을 JavaScript에 노출시키지 않습니다 . 그럼에도 불구하고 HTTP / 2 연결을 통해 동일한 오리진에 대해 여러 요청을하는 경우 해당 트래픽의 모든 연결이 하나의 연결에서 다중화됩니다 (우리가 염려하는 것입니다).
따라서 실시간 채팅 앱을 구축해야하는 경우 연결이 열려있는 채팅방의 모든 클라이언트에게 새 채팅 메시지를 브로드 캐스트해야하는 경우 웹 소켓없이이 작업을 수행 할 수 있습니다.
Server-Sent Events를 사용하여 메시지를 푸시 다운하고 Fetch api를 사용하여 요청을 보냅니다. SSE ( Server-Sent Events )는 잘 알려지지 만 잘 지원되는 API로 메시지 지향 서버-클라이언트 스트림을 노출합니다. 클라이언트 JavaScript에서는 보이지 않지만 브라우저 (HTTP / 2를 지원하는 경우)에서 단일 TCP 연결을 재사용하여 모든 메시지를 다중화합니다. 효율성 손실이 없으며 실제로 웹 소켓보다 이점이 있습니다. 여러 스트림이 필요하십니까? 여러 이벤트 소스를 엽니 다! 그들은 당신을 위해 자동으로 멀티플렉싱됩니다.
서버 소켓 이벤트는 웹 소켓 핸드 셰이크보다 리소스 효율성이 뛰어나고 초기 대기 시간이 짧을뿐만 아니라 HTTP / 1.1에서 자동으로 대체되어 작동하는 좋은 속성을 갖습니다. 그러나 HTTP / 2 연결이 있으면 매우 잘 작동합니다.
다음 은 반응 적으로 업데이트되는 SPA를 달성 하는 실제 사례 를 보여주는 좋은 기사입니다 .
나는 Nay라고 말합니다 ( 웹 소켓은 더 이상 사용되지 않습니다 ).
가장 일반적으로 무시되는 문제는 HTTP / 2 푸시가 적용되지 않으며 프록시, 라우터, 기타 중개자 또는 브라우저에 의해 무시 될 수 있다는 것 입니다.
즉 (HTTP2 초안에서) :
중개자는 서버에서 푸시를 수신 하고 클라이언트로 푸시 하지 않도록 선택할 수 있습니다 . 다시 말해, 푸시 된 정보를 사용하는 방법은 해당 중개자에게 달려 있습니다. 마찬가지로 중개자는 서버에 의한 조치없이 클라이언트에 추가 푸시를 수행 할 수 있습니다.
따라서 HTTP / 2 푸시는 WebSocket을 대체 할 수 없습니다.
또한 HTTP / 2 연결은 잠시 후에 닫힙니다.
표준에 따르면 다음과 같습니다.
HTTP / 2 연결은 영구적입니다. 최상의 성능을 위해서는 클라이언트가 서버와의 추가 통신이 필요하지 않다고 판단 될 때 (예 : 사용자가 특정 웹 페이지에서 다른 곳으로 이동할 때) 또는 서버가 연결을 닫을 때까지 연결을 닫지 않을 것으로 예상됩니다.
그러나...
서버는 가능한 한 오랫동안 열린 연결을 유지하는 것이 좋지만 필요한 경우 유휴 연결을 종료 할 수 있습니다. 어느 엔드 포인트가 전송 계층 TCP 연결을 닫으려고 선택하면, 종단 엔드 포인트는 먼저 GOAWAY (섹션 6.8) 프레임을 전송하여 두 엔드 포인트가 이전에 전송 된 프레임이 처리되었는지 여부를 확인하고 필요한 나머지 작업을 정상적으로 완료하거나 종료 할 수 있도록해야합니다.
동일한 연결이 컨텐츠가 열려있는 동안 컨텐츠를 푸시 할 수 있고 HTTP / 2가 HTTP / 1.1의 'keep-alive'에 의해 발생 된 일부 성능 문제를 해결하더라도 HTTP / 2 연결은 무기한으로 열려 있지 않습니다. .
웹 페이지가 일단 닫힌 후에는 HTTP / 2 연결을 다시 시작할 수 없습니다 (긴장으로 돌아 오지 않는 한).
편집 (2017 년, 2 년 후)
HTTP / 2를 구현하면 여러 개의 브라우저 탭 / 윈도우가 단일 HTTP / 2 연결을 공유한다는 것을 push
알 수 있습니다. 즉, 어떤 탭 / 창이 속하는지 알 수 없으므로 push
웹 소켓을 대체 할 필요가 없습니다.
편집 (2020)
사람들이 왜 답을 내리기 시작했는지 잘 모르겠습니다. 대답이 처음 게시 된 이후 몇 년 동안 HTTP / 2가 WebSocket을 대체 할 수없고 그렇게 설계되지 않았 음을 증명했습니다.
물론, HTTP / 2는 WebSocket 연결 을 터널링 하는 데 사용될 수 있지만 이러한 터널링 된 연결에는 여전히 WebSocket 프로토콜이 필요하며 HTTP / 2 컨테이너의 작동 방식에 영향을 미칩니다.
ssh
웹 소켓을 사용하는 경우 브라우저 에서 터미널을 구현하는 것이 매우 쉽습니다. 특히 두 개 이상의 탭이 열려있는 경우 HTTP / 2에서 문제가 될 수 있습니다. 또한 브라우저 (또는 HTTP / 2 프록시 중 하나)가 연결을 닫으면 어떻게됩니까? 고객은 새로운 데이터가 없다고 가정 할 수 있습니까? 우리는 다시 폴링으로 돌아 왔습니다.
onclose
콜백을 지원 하므로 폴링이 필요하지 않습니다. 멀티플렉싱은 선택이 아니라 필수라고 생각합니다. keep-alive
"선에서"성능 저하를 피할 수있는 유일한 방법은 멀티플렉싱의 위험이었습니다. 시간은 말할 것이다 :)
내 대답은 아니오 야. 둘 사이의 목표는 매우 다릅니다. HTTP / 2를 통한 WebSocket 용 RFC도있어 단일 HTTP / 2 TCP 파이프를 통해 여러 개의 WebSocket을 연결할 수 있습니다.
HTTP over WS / 2는 새로운 연결을 여는 데 걸리는 시간을 줄이고 소켓, 소프트 IRQ 및 버퍼를 추가하지 않고도 더 많은 통신 채널을 허용함으로써 자원 절약 효과가 있습니다.
https://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01
이 InfoQ 기사 에서 인용하자면 다음과 같습니다 .
우리가 위에서 본 것처럼 HTTP / 2는 서버 푸시를 서버가 클라이언트 캐시에 능동적으로 보낼 수있게하는 서버 푸시를 도입했습니다. 그러나 데이터를 클라이언트 응용 프로그램 자체로 푸시 할 수는 없습니다. 서버 푸시는 브라우저에 의해서만 처리되며 애플리케이션 코드에 팝업되지 않으므로 애플리케이션이 해당 이벤트에 대한 알림을받는 API가 없습니다.
따라서 HTTP2 푸시는 실제로 브라우저와 서버 사이의 무언가이며 웹 소켓은 실제로 클라이언트 (브라우저에서 실행되는 경우 자바 스크립트)와 실시간 데이터 전송을 위해 응용 프로그램 코드 (서버에서 실행)에서 사용할 수있는 API를 노출합니다.
메시지 교환 및 간단한 스트리밍 (오디오, 비디오 스트리밍 아님)은 Http / 2 멀티플렉싱 및 WebSocket을 통해 수행 할 수 있습니다. 따라서 약간의 중복이 있지만 WebSockets는 프로토콜, 많은 프레임 워크 / API 및 헤더 오버 헤드가 적습니다. 여기 주제에 관한 좋은 기사가 있습니다.
HTTP / 2에는 WebSocket 구현이 있습니다. https://tools.ietf.org/html/rfc8441
2020 년 4 월 현재, HTTP / 2는 WebSocket을 더 이상 사용하지 않습니다. HTTP2에 비해 WebSocket의 가장 큰 장점은
HTTP/2 works only on Browser Level not Application Level
HTTP / 2는 WebSockets와 같은 JS API를 제공하여 통신을 허용하고 어떤 종류의 JSON 또는 기타 데이터를 응용 프로그램 (예 : 웹 사이트)에서 서버로 직접 전송할 수 있도록합니다. 따라서 내가 생각하는 한 HTTP / 2는 WebSocket과 같은 API를 서버와 통신하기 시작하면 WebSockets를 쓸모 없게 만듭니다. HTTP 1.1의 최신 버전으로 업데이트 될 때까지.
오늘 현재
HTTP와 비교하여 HTTP / 2를 사용하면 서버와의 연결을 유지할 수 있습니다. 여기에서 동시에 여러 데이터 스트림을 가질 수 있습니다. 클라이언트가 요청하지 않아도 여러 항목을 동시에 푸시 할 수 있습니다. 예를 들어, 브라우저가을 요청 index.html
하면 서버는 푸시 index.css
및index.js
됩니다. 브라우저가 요청하지 않았지만 서버는 몇 초 안에 원하는 것으로 가정 할 수 있기 때문에 요청없이 서버에서 제공 할 수 있습니다.
이 빨라지고의 HTTP / 1 대안보다 index.html
이 필요로 발견, 그것을 구문 분석 index.js
하고 index.css
및 다음 해당 파일이 개 다른 요청을 구축. HTTP / 2를 통해 서버는 클라이언트가 요청하지 않은 데이터를 푸시 할 수 있습니다.
이러한 맥락에서 WebSocket과 비슷하지만 실제로는 설계에 따라 다릅니다. WebSocket은 TCP 연결 또는 직렬 연결과 유사한 양방향 통신을 허용해야합니다. 둘 다 서로 통신하는 소켓입니다. 또한 가장 큰 차이점은 HTTP 프로토콜로 캡슐화되지 않은 임의의 데이터 패킷을 원시 바이트로 보낼 수 있다는 것입니다. 헤더, 경로, 쿼리 문자열의 개념은 핸드 셰이크 중에 만 발생하지만 WebSocket은 데이터 스트림을 엽니 다.
또 다른 차이점은 Javascript에서 WebSocket에 훨씬 더 미세하게 액세스 할 수있는 반면, HTTP에서는 브라우저가 처리한다는 것입니다. HTTP를 통해 얻을 수있는 것은 XHR
/에 맞는 것입니다 fetch()
. (: 예, 그것은 또한 브라우저가 당신이 그것을 제어 할 수없이 차단 및 수정 HTTP 헤더에 도착 의미 Origin
, Cookies
등). 또한, HTTP / 2가 푸시 할 수있는 것은 브라우저로 전송됩니다. 즉, JS는 항상 추진되고있는 것을 항상 알고있는 것은 아닙니다. 다시 말하지만, 그것은을 위해 의미가 index.css
와 index.js
브라우저가 캐시,하지만 너무 많은 데이터 패킷 때문이다.
그것은 실제로 모든 이름입니다. HTTP는 HyperText Transfer Protocol의 약어입니다. 우리는 자산 이전 개념에 중점을두고 있습니다. WebSocket은 바이너리 데이터가 양방향으로 전달되는 소켓 연결을 구축하는 것입니다.
실제로 논의하지 않은 것은 SSE (Server-Sent Events)입니다. 애플리케이션 (JS)으로 데이터를 푸시하는 것은 HTTP / 2의 의도는 아니지만 SSE를위한 것입니다. SSE는 HTTP / 2로 강화되었습니다. 그러나 변수 엔드 포인트에 도달하지 않고 데이터 자체가 중요한 경우 WebSocket을 대체 할 수는 없습니다. WebSocket을 사용하는 각 엔드 포인트에 대해 새 데이터 스트림이 작성되지만 SSE를 사용하면 기존 HTTP / 2 세션간에 공유됩니다.
각각의 목표는 다음과 같습니다.