HTTP 폴링, 롱 폴링, HTTP 스트리밍 및 WebSocket에 대한 나의 이해


123

나는 내 질문 제목의 키워드와 관련하여 SO 및 웹에서 많은 게시물을 읽고 많은 것을 배웠습니다. 내가 읽은 질문 중 일부는 특정 구현 문제와 관련이 있으며 다른 질문은 일반적인 개념에 중점을 둡니다. 저는 모든 개념과 기술 X가 기술 Y를 넘어서 발명 된 이유를 이해했는지 확인하고 싶습니다. 그래서 여기에 간다 :

Http 폴링 : 기본적으로 XmlHttpRequest를 사용하는 AJAX.

Http Long Polling : AJAX이지만 서버에 업데이트가없는 경우 서버는 응답을 유지합니다. 서버에 업데이트가있는 즉시 전송 한 다음 클라이언트가 다른 요청을 보낼 수 있습니다. 단점은 추가 오버 헤드를 유발하는 앞뒤로 전송되어야하는 추가 헤더 데이터입니다.

Http 스트리밍 : 긴 폴링 유사하지만 서버는 "Transfer Encoding : chunked"로 헤더로 응답하므로 서버가 일부 데이터를 보낼 때마다 새 요청을 시작할 필요가 없으므로 추가 헤더 오버 헤드를 절약 할 수 있습니다. 여기서 단점은 서버에서 보낸 여러 청크를 구분하기 위해 데이터 구조를 "이해"하고 파악해야한다는 것입니다.

Java Applet, Flash, Silverlight : tcp / ip를 통해 소켓 서버에 연결할 수있는 기능을 제공하지만 플러그인이기 때문에 개발자는 이에 의존하고 싶지 않습니다.

WebSockets : 위 메서드의 단점을 다음과 같은 방식으로 해결하려는 새로운 API입니다.

  • Java Applets, Flash 또는 Silverlight와 같은 플러그인에 비해 WebSocket의 유일한 장점은 WebSocket이 기본적으로 브라우저에 내장되어 있으며 플러그인에 의존하지 않는다는 것입니다.
  • http 스트리밍에 비해 WebSockets의 유일한 장점은 수신 된 데이터를 "이해"하고 구문 분석하기 위해 노력할 필요가 없다는 것입니다.
  • 긴 폴링에 비해 WebSockets의 유일한 장점은 추가 헤더 크기를 제거하고 요청에 대한 소켓 연결을 열고 닫는 것입니다.

내가 놓친 다른 중요한 차이점이 있습니까? 이미 SO에 대한 많은 질문을 하나의 질문으로 다시 묻거나 결합하면 미안하지만 이러한 개념과 관련하여 SO 및 웹에있는 모든 정보를 완벽하게 이해하고 싶습니다.

감사!


4
양방향 통신이 필요하지 않은 경우 Server-Sent Events 를 살펴볼 수도 있습니다.
leggetter

1
이것은 정말 유용한 질문입니다. 여러 저자가 기여할 수있는 답변이 하나만 있다면 더 유용 할 것이라고 생각합니다.
leggetter

@leggetter 감사합니다 Phil, 서버 전송 이벤트에 관한 팁을 주셔서 감사합니다. 양방향 커뮤니케이션 시나리오에 대해 배우고 싶습니다. 감사.
소프트웨어 가이

1
HTTP 스트리밍 및 롱 폴링을 사용하려면 양방향 통신을위한 두 번째 연결이 필요합니다. 서버-> 클라이언트 '푸시'통신을위한 하나의 긴 연결과 클라이언트-> 서버 통신을위한 두 번째 짧은 연결. 이 두 번째 연결은 데이터에 대한 구독 설정 및 변경과 같은 작업을 수행하는 데 사용됩니다. 따라서 EventSource는 양방향 솔루션에서 사용할 수 있으며 실제로는 HTTP 스트리밍 및 Long-Polling에서 태어난 표준화 된 솔루션입니다.
leggetter

1
: 당신은 또한 내가 쓴 기술의 분류를 확인 할 수 있습니다 stackoverflow.com/questions/12078550/...
알레산드로 Alinone

답변:


92

당신이 확인한 것보다 더 많은 차이점이 있습니다.

이중 / 방향 :

  • 단방향 : HTTP 폴, 롱 폴, 스트리밍.
  • 양방향 : WebSockets, 플러그인 네트워킹

지연 시간을 늘리는 순서 (대략) :

  • WebSockets
  • 플러그인 네트워킹
  • HTTP 스트리밍
  • HTTP 긴 폴링
  • HTTP 폴링

CORS (교차 출처 지원) :

  • WebSockets : 예
  • 플러그인 네트워킹 : 정책 요청을 통한 플래시 (다른 사람에 대해서는 확실하지 않음)
  • HTTP * (최근 지원)

네이티브 바이너리 데이터 (형식화 된 배열, Blob) :

  • WebSockets : 예
  • 플러그인 네트워킹 : Flash를 사용하지 않음 (ExternalInterface를 통한 URL 인코딩 필요)
  • HTTP * : 바이너리 유형 지원을 활성화하기위한 최근 제안

효율성 감소의 대역폭 :

  • 플러그인 네트워킹 : 초기 정책 요청을 제외하고 플래시 소켓은 원시입니다.
  • WebSockets : 연결 설정 핸드 셰이크 및 프레임 당 몇 바이트
  • HTTP 스트리밍 (서버 연결 재사용)
  • HTTP 긴 폴 : 모든 메시지에 대한 연결
  • HTTP 폴 : 모든 메시지에 대한 연결 + 데이터 메시지 없음

모바일 장치 지원 :

  • WebSocket : iOS 4.2 이상. Flash 에뮬레이션을 통한 일부 Android 또는 Android 용 Firefox 또는 Android 용 Google Chrome을 사용 하며 둘 다 기본 WebSocket 지원을 제공합니다.
  • 플러그인 네트워킹 : 일부 Android. iOS가 아님
  • HTTP * : 대부분 예

자바 스크립트 사용 복잡성 (가장 단순한 것부터 가장 복잡한 것까지). 물론 복잡성 측정은 다소 주관적입니다.

  • WebSockets
  • HTTP 설문 조사
  • 플러그인 네트워킹
  • HTTP 긴 폴링, 스트리밍

또한 Server-Sent Events 라는 HTTP 스트리밍을 표준화하기위한 W3C 제안이 있습니다 . 현재는 진화 단계의 초기 단계이며 WebSocket과 비슷한 단순성을 갖춘 표준 Javascript API를 제공하도록 설계되었습니다.


1
카나 카의 좋은 답변에 감사드립니다. 왜 http 스트리밍이 웹 소켓보다 지연 시간이 더 긴지 알려주시겠습니까? 간단한 예를 들면? 감사합니다.
Software Guy

2
@SoftwareGuy. 많은 이유. 최근 브라우저에서는 XMLHTTPRequest onprogress 이벤트 핸들러를 사용하여 데이터를 알릴 수 있습니다. 그러나 사양에 따르면 50ms가 가장 작은 알림 간격입니다. 그렇지 않으면 응답 데이터를 폴링해야합니다. 또한 클라이언트 전송은 새로운 HTTP 연결을 설정하므로 왕복 대기 시간이 크게 늘어납니다. 또한 많은 웹 서버가 30 초 정도 후에 HTTP 연결을 끊기 때문에 서버 푸시 연결을 계속 다시 설정해야하는 경우가 많습니다. 로컬 네트워크에서 5-10ms WebSocket 왕복 대기 시간을 보았습니다. HTTP 스트리밍 지연 시간은 50ms 이상입니다.
kanaka

감사합니다 :) 자세한 답변에 대한 많은
소프트웨어 가이

1
@leggetter 감사합니다 Phil, http 스트리밍을 통해 클라이언트에서 서버로 데이터를 전송하면 오버 헤드가 발생한다는 의미입니까? 새로운 연결을 열지 않고도 http 스트리밍을 통해 서버에 데이터를 보낼 수 있습니까? 감사.
Software Guy

1
@Nathan은 좋은 석사 학위 논문 프로젝트처럼 들립니다! 물론 폴링은 이벤트 기반 모델보다 시스템을 더 바쁘게 유지하지만 정확히 어떤 전력 절감을 위해서는 다양한 규모에서 상당히 광범위한 실증 테스트가 필요합니다.
kanaka

13

많은 근거를 다루는 다른 사람들의 훌륭한 답변. 여기에 약간의 추가 정보가 있습니다.

Java Applets, Flash 또는 Silverlight와 같은 플러그인에 비해 WebSocket의 유일한 장점은 WebSocket이 기본적으로 브라우저에 내장되어 있으며 플러그인에 의존하지 않는다는 것입니다.

이것이 Java Applets, Flash 또는 Silverlight를 사용하여 소켓 연결을 설정할 수 있음을 의미한다면 가능합니다. 그러나 제한으로 인해 실제 세계에 너무 자주 배포되는 것을 보지 못합니다.

예를 들어 중개자는 해당 트래픽을 차단할 수 있습니다. WebSocket 표준은 기존 HTTP 인프라와 호환되도록 설계되었으므로 방화벽 및 프록시와 같은 중개자의 간섭을 훨씬 덜받습니다.

또한 WebSocket은 기존 HTTP 인프라와 최대한 호환되는 프로토콜 설계 덕분에 전용 포트없이 포트 80 및 443을 사용할 수 있습니다.

이러한 소켓 대안 (Java, Flash 및 Silverlight)은 교차 출처 아키텍처에서 안전하게 사용하기가 어렵습니다. 따라서 종종 교차 출처를 사용하려고 시도하는 사람들은 안전하게 수행하려는 노력보다 불안정성을 용인 할 것입니다.

또한 추가 "비표준"포트를 열어야하거나 (관리자가 싫어하는 일) 관리해야하는 정책 파일이 필요할 수 있습니다.

요컨대, 소켓 연결을 위해 Java, Flash 또는 Silverlight를 사용하는 것은 심각한 아키텍처에 너무 자주 배포되는 것을 보지 못할만큼 문제가됩니다. 플래시와 자바는 아마도 적어도 10 년 동안이 기능을 가지고 있었지만 널리 퍼지지는 않았습니다.

WebSocket 표준은 이러한 제한 사항을 염두에두고 새로운 접근 방식으로 시작할 수 있었으며 그로부터 몇 가지 교훈을 얻었기를 바랍니다.

일부 WebSocket 구현은 WebSocket 연결을 설정할 수없는 경우 (예 : 이전 브라우저에서 실행 중이거나 중개자가 방해하는 경우) 대체 수단으로 Flash (또는 Silverlight 및 / 또는 Java)를 사용합니다.

이러한 상황에 대한 일종의 폴백 전략이 현명하고 필요하지만 Flash 등을 사용하는 대부분의 경우 위에서 설명한 단점이 있습니다. 그렇게 할 필요는 없습니다. Flash, Silverlight 등을 사용하여 안전한 교차 출처 연결을 달성하기위한 해결 방법이 있지만 대부분의 구현은 쉽지 않기 때문에 그렇게하지 않습니다.

예를 들어, 교차 출처 연결을 위해 WebSocket에 의존하는 경우 제대로 작동합니다. 그러나 이전 브라우저에서 실행하거나 방화벽 / 프록시가 방해를 받아 플래시에 의존하는 경우 (예 : 폴백으로) 동일한 교차 출처 연결을 수행하기가 어렵습니다. 물론 보안에 신경 쓰지 않는 한.

즉, 상당한 작업을 할 준비가되어 있거나 잘 수행 된 프레임 워크를 사용하지 않는 한 네이티브 및 비 네이티브 연결에 대해 작동하는 단일 통합 아키텍처를 갖는 것이 어렵습니다. 이상적인 아키텍처에서는 연결이 기본인지 아닌지 알 수 없습니다. 보안 설정은 두 경우 모두 작동합니다. 클러스터링 설정은 계속 작동합니다. 용량 계획은 여전히 ​​유효합니다. 등등.

http 스트리밍에 비해 WebSockets의 유일한 장점은 수신 된 데이터를 "이해"하고 구문 분석하기 위해 노력할 필요가 없다는 것입니다.

HTTP 스트림을 열고 데이터가 몇 분, 몇 시간 또는 그 이상 흐름을 유지하는 것처럼 간단하지 않습니다. 클라이언트마다 다르게 행동하므로이를 관리해야합니다. 예를 들어 일부 클라이언트는 데이터를 버퍼링하고 일부 임계 값이 충족 될 때까지 애플리케이션에 릴리스하지 않습니다. 더 나쁜 것은 일부는 연결이 닫힐 때까지 데이터를 애플리케이션에 전달하지 않는다는 것입니다.

따라서 여러 메시지를 클라이언트로 보내는 경우, 예를 들어 50 개의 메시지에 해당하는 데이터가 수신 될 때까지 클라이언트 응용 프로그램이 데이터를 수신하지 못할 수 있습니다. 너무 실시간이 아닙니다.

HTTP 스트리밍은 WebSocket을 사용할 수 없을 때 실행 가능한 대안이 될 수 있지만 만병 통치약은 아닙니다. 실제 환경에서 웹의 황무지에서 강력한 방식으로 작업하려면 좋은 이해가 필요합니다.

내가 놓친 다른 중요한 차이점이 있습니까?

아직 아무도 언급하지 않은 것이 하나 더 있으므로 제가 말씀 드리겠습니다.

WebSocket 프로토콜은 높은 수준의 프로토콜을위한 전송 계층으로 설계되었습니다. WebSocket 연결을 통해 직접 JSON 메시지 또는 기타 메시지를 보낼 수 있지만 표준 또는 사용자 지정 프로토콜을 전달할 수도 있습니다.

예를 들어, 사람들이 이미 한 것처럼 WebSocket을 통해 AMQP 또는 XMPP를 수행 할 수 있습니다. 따라서 클라이언트는 마치 브로커 자체에 직접 연결된 것처럼 AMQP 브로커로부터 메시지를 수신 할 수 있습니다 (경우에 따라 연결됨).

또는 일부 사용자 지정 프로토콜이있는 기존 서버가있는 경우 WebSocket을 통해이를 전송하여 해당 백엔드 서버를 웹으로 확장 할 수 있습니다. 종종 엔터프라이즈에 잠겨있는 기존 애플리케이션은 백엔드 인프라를 변경하지 않고도 WebSocket을 사용하여 범위를 확장 할 수 있습니다.

(당연히 모든 작업을 안전하게 수행 할 수 있기를 원하므로 공급 업체 또는 WebSocket 제공 업체에 문의하십시오.)

어떤 사람들은 WebSocket을 웹용 TCP라고합니다. TCP가 더 높은 수준의 프로토콜을 전송하는 것과 마찬가지로 WebSocket도 웹 인프라와 호환되는 방식으로 전송되기 때문입니다.

따라서 WebSocket을 통해 직접 JSON (또는 기타) 메시지를 보내는 것은 항상 가능하지만 기존 프로토콜도 고려해야합니다. 왜냐하면 당신이하고 싶은 많은 일들에 대해 이미 그것을 할 것으로 생각 된 프로토콜이있을 것입니다.

이미 SO에 대한 많은 질문을 하나의 질문으로 다시 묻거나 결합하면 미안하지만 이러한 개념과 관련하여 SO 및 웹에있는 모든 정보를 완벽하게 이해하고 싶습니다.

이것은 훌륭한 질문이었고 답변은 모두 매우 유익했습니다!


훌륭한 도움과 정보를 주신 Robin에게 감사드립니다. 한 가지 더 물어볼 수 있습니다. http 스트리밍이 프록시에 의해 캐시 될 수 있지만 웹 소켓은 캐시되지 않는다는 기사를 보았습니다. 그게 무슨 뜻이야?
소프트웨어 가이

: StackOverflow의 응답 주석의 크기를 제한하기 때문에, 나는 내 대답은 아래 준 stackoverflow.com/questions/12555043/...
로빈 짐머만

@RobinZimmermann, 당신의 대답은 내가 가장 좋아하는 것입니다. 정말 좋은 자세한 답변은 +1입니다.
securecurve

10

한 가지 더 물어볼 수 있습니다. http 스트리밍이 프록시에 의해 캐시 될 수 있지만 웹 소켓은 캐시되지 않는다는 기사를 보았습니다. 그게 무슨 뜻이야?

(StackOverflow는 댓글 응답의 크기를 제한하므로 인라인이 아닌 여기에서 답변해야했습니다.)

그건 좋은 지적이야. 이것을 이해하기 위해 전통적인 HTTP 시나리오를 생각해보십시오. 브라우저가 웹 페이지를 열어 http://example.com 을 요청한다고 가정 해보십시오 . 서버는 페이지에 대한 HTML이 포함 된 HTTP로 응답합니다. 그런 다음 브라우저는 페이지에 리소스가 있음을 확인하고 CSS 파일, JavaScript 파일 및 이미지 요청을 시작합니다. 요청하는 모든 클라이언트에 대해 동일 할 모든 정적 파일입니다 .

일부 프록시는 정적 리소스를 캐시하여 다른 클라이언트의 후속 요청이 해당 정적 리소스를 얻기 위해 중앙 웹 서버로 완전히 돌아 가지 않고 프록시에서 가져올 수 있도록합니다. 이것은 캐싱이며 중앙 서비스에서 요청 및 처리를 오프로드하는 훌륭한 전략입니다.

따라서 클라이언트 # 1은 http://example.com/images/logo.gif 요청합니다 . 이 요청은 프록시를 통해 logo.gif를 제공하는 중앙 웹 서버까지 전달됩니다. logo.gif가 프록시를 통과하면 프록시는 해당 이미지를 저장하고 http://example.com/images/logo.gif 주소와 연결합니다 .

클라이언트 # 2가 나타나서 http://example.com/images/logo.gif 를 요청 하면 프록시가 이미지를 반환 할 수 있으며 센터의 웹 서버로 다시 통신 할 필요가 없습니다. 이는 최종 사용자에게 더 빠른 응답을 제공하며 이는 항상 훌륭하지만 센터에 대한 부하가 적다는 의미이기도합니다. 이는 하드웨어 비용 절감, 네트워킹 비용 절감 등으로 이어질 수 있습니다. 따라서 좋은 일입니다.

웹 서버에서 logo.gif가 업데이트되면 문제가 발생합니다. 프록시는 새 이미지가 있다는 것을 인식하지 못한 채 이전 이미지를 계속 제공합니다. 이로 인해 프록시가 "만료"되기 전에 짧은 시간 동안 만 이미지를 캐시하고 다음 요청이 프록시를 통해 웹 서버로 이동 한 다음 프록시의 캐시를 새로 고치도록 만료 될 때까지 모든 일이 발생합니다. 중앙 서버가 알려진 캐시 등으로 푸시 할 수있는 고급 솔루션도 있으며 상황이 매우 정교해질 수 있습니다.

이것이 귀하의 질문과 어떤 관련이 있습니까?

서버가 HTTP를 클라이언트로 스트리밍하는 HTTP 스트리밍에 대해 질문했습니다. 그러나 스트리밍 HTTP는 데이터 전송을 중단하지 않는다는 점을 제외하면 일반 HTTP와 같습니다. 웹 서버가 이미지를 제공하면 결국 종료되는 클라이언트에 HTTP를 보냅니다. 전체 이미지를 보냈습니다. 데이터를 보내고 싶다면 정확히 똑같지 만, 서버는 정말 오랜 시간 동안 (예를 들어, 엄청나게 거대한 이미지처럼) 전송하거나 끝나지 않습니다.

프록시의 관점에서 보면 이미지와 같은 정적 리소스에 대한 HTTP와 HTTP 스트리밍의 데이터를 구분할 수 없습니다. 두 경우 모두 클라이언트가 서버에 요청했습니다. 프록시는 그 요청과 응답도 기억했습니다. 다음에 해당 요청이 들어 오면 프록시는 동일한 응답을 제공합니다.

따라서 고객이 주가를 요청하고 응답을 받으면 다음 고객이 동일한 요청을하고 캐시 된 데이터를 가져올 수 있습니다. 아마도 당신이 원하는 것이 아닐 것입니다! 주가를 요청하면 최신 데이터를 원 하시죠?

그래서 그것은 문제입니다.

이와 같은 문제를 처리하기위한 트릭과 해결 방법이 있습니다. 사실입니다. HTTP 스트리밍이 오늘날 사용되고 있기 때문에 분명히 작동하도록 할 수 있습니다. 최종 사용자에게는 모두 투명하지만 이러한 아키텍처를 개발하고 유지 관리하는 사람들은 대가를 치르고 비용을 지불해야합니다. 그 결과 아키텍처가 지나치게 복잡해지며, 이는 더 많은 유지 관리, 더 많은 하드웨어, 더 많은 복잡성, 더 많은 비용을 의미합니다. 또한 개발자는 애플리케이션, GUI 및 비즈니스 로직에만 집중해야 할 때 필요하지 않아야 할 일에 관심을 가져야하는 경우가 많습니다. 기본 통신에 대해 걱정할 필요가 없습니다.


1
훌륭한 디테일 로빈, 정말 감사합니다! 철저한 답변에 감사드립니다. 나는 이미 여기있는 모든 위대한 사람들로부터 많은 것을 배웠습니다! :)
Software Guy

4

HTTP는 클라이언트가 서버와 가질 수있는 연결 수를 2로 제한하고 (하위 도메인을 사용하여 완화 할 수 있음) IE는이를 강력하게 시행하는 것으로 알려져 있습니다. Firefox와 Chrome은 더 많은 것을 허용합니다 (정확히 몇 개인 지 기억할 수는 없지만). 이것은 큰 문제처럼 보이지 않을 수 있지만 실시간 업데이트를 위해 지속적으로 하나의 연결을 사용하는 경우 다른 모든 요청은 다른 HTTP 연결을 통해 병목 현상이 발생해야합니다. 그리고 클라이언트에서 더 많은 연결이 열려 있으면 서버에 더 많은 부하가 걸리는 문제가 있습니다.

WebSocket은 TCP 기반 프로토콜이므로 이러한 HTTP 수준 연결 제한이 없습니다 (물론 브라우저 지원은 균일하지 않습니다).


감사합니다 thejuice, 그래서 당신이 강조한 다중 동시 연결 문제 외에 웹 소켓에 관한 나머지 가정이 맞습니까?
소프트웨어 가이
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.