19

서버 보낸 이벤트를 수신하는 웹 응용 프로그램이 있습니다. 여러 창을 열어보고 작업하고 테스트하는 동안 문제가 발생하지 않았으며 잘못된 방향으로 몇 번이나 머리를 숙였습니다. 결국 문제는 동시 연결이라는 것을 깨달았습니다.서버에서 보낸 이벤트 및 브라우저 제한

그러나 매우 제한된 수를 테스트 중이 었으며 Apache에서 테스트를 실행 중이더라도 (노드를 사용해야 함) 알아 두십시오.

그런 다음 브라우저를 전환하여 정말 흥미로운 것을 발견했습니다. 오페라는 그렇지 않지만 크롬은 서버 보낸 이벤트 연결을 4-5로 제한합니다. 반면 Firefox는 4-5 개의 동시 연결 후 다른 페이지를로드하지 않습니다.

이유가 무엇입니까? 이 제한은 동일한 소스의 SSE 연결에만 적용됩니까? 아니면 다른 도메인에서 테스트를 열려고해도 동일한 것입니까? SSE를 오용하고 브라우저를 실제로 차단할 가능성이 있습니까? 아니면 이것은 알려진 동작입니까? 그 주위에 어떤 방법이 있습니까?

+0

(Windows)은 IE, 크롬 및 파이어 폭스와 관련된 레지스트리 설정에 의해 제어되며 SSE가 아닌 모든 연결을 제한합니다. 나는 웹 소켓과 같은 문제를 가지고있다. 당신은 이것을 만들 수 없다 ... – dandavis

답변

26

모든 브라우저에서이 방식이 작동하는 방식은 각 도메인이 제한된 연결 수를 얻고 전체 응용 프로그램에 대해 제한이 적용된다는 것입니다. 즉, 실시간 통신을 위해 하나의 연결이 열려 있으면 이미지, CSS 및 기타 페이지를로드하기위한 연결이 하나 더 적음을 의미합니다. 그 외에 새로운 탭이나 창에 대한 새로운 연결을 얻지는 못합니다. 모두 동일한 연결을 공유해야합니다. 이것은 매우 실망 스럽지만 연결을 제한하는 좋은 이유가 있습니다. 몇 년 전만해도이 제한은 (http://www.ietf.org/rfc/rfc2616.txt) HTTP1.1 스펙의 규칙에 따라 모든 브라우저에서 2 였지만 이제 대부분의 브라우저는 일반적으로 4-10 개의 연결을 사용합니다. 반면에 모바일 브라우저는 배터리 절약을 위해 연결량을 제한해야합니다.

이 트릭을 사용할 수 있습니다

  1. 사용 이상의 호스트 이름. ex. www1.domain.com, www2.domain.com을 사용하면 각 호스트 이름에 대해 새로운 연결을 얻을 수 있습니다. 이 트릭은 모든 브라우저에서 작동합니다. 전체 도메인 (www.domain.com이 아닌 domain.com)을 포함하도록 쿠키 도메인을 변경하는 것을 잊지 마십시오.
  2. 웹 소켓을 사용하십시오. 웹 소켓은 이러한 제한 사항에 의해 제한되지 않으며 더 중요한 것은 다른 웹 사이트 콘텐츠와 경쟁하지 않는다는 것입니다.
  3. 새 탭/창을 열 때 동일한 연결을 다시 사용하십시오.

    window.hub = window.opener ? window.opener.hub || new Hub()

  4. 또는 플래시를 사용 - 꽤 최선의 충고 요즘하지만 여전히 수 있습니다 : 당신이 객체 호출 허브에 모든 실시간 통신 논리를 수집 한 경우이 같은 열려있는 모든 창에 해당 개체를 호출 할 수 있습니다 웹 소켓이 옵션이 아닌 경우 옵션.
  5. 새 SSE 요청을 시작하기 전에 대기열에있는 요청을 지울 수 있도록 각 SSE 요청 사이에 몇 초의 시간을 추가하십시오. 또한 사용자가 비활성 상태 일 때 잠깐 기다리는 시간을 조금 더 늘리면 서버 리소스를 활성 상태 인 사용자에게 집중시킬 수 있습니다.또한 멀티 스레드 및 차단 언어 자바와 같은 또는 C# 당신의 나머지 부분에 대한 필요 당신의 긴 폴링 요청에 자원을 사용하여 위험을 사용할 때 기억해야 할 Thundering Herd Problem

또 다른 일을 방지하기 위해 지연의 임의의 숫자를 추가하려면 신청. 예를 들어 C#에서는 각 요청이 Session 객체를 잠급니다. 즉, SSE 요청이 활성화되는 동안 전체 응용 프로그램이 응답하지 않습니다.

NodeJs는 이미 알아 냈으므로 여러 가지 이유로 좋으며 NodeJS를 사용하는 경우 socket.io 또는 engine.io를 사용하면 웹 소켓, 플래시 소켓을 사용하여 이러한 모든 문제를 해결할 수 있습니다. XHR 폴링 및 비 블로킹 및 단일 스레드이기 때문에 서버에서 리소스를 보낼 때까지 기다리지 않을 때 리소스를 거의 소비하지 않습니다. C# 응용 프로그램은 대기중인 요청 당 하나의 스레드를 사용하며 스레드에 대해 2MB 이상의 메모리가 필요합니다.

+1

큰 대답! Firefox가 다른 도메인을 열지 못하는 이유를 알고 계십니까? – Sunyatasattva

+0

감사합니다. 불행히도 window.opener 트릭은 내 응용 프로그램에서 만든 하위 창에서만 작동합니다. 사용자가 열어 본 탭이 아닙니다. 사용자가 너무 많은 탭을 열 자마자 나는 망했다 ... 열려있는 모든 연결을 다 써 버릴지를 확인하는 방법이 있는지 아십니까? – phtrivier

+0

두 시나리오를 처리 할 (window.parent || window.opener)를 사용해보십시오. 또한 교차 탭 메시지를 보내는 postMessage 메서드를 살펴보십시오. 연결량을 확인할 방법이 없다고 생각하지만 긴 폴링 요청이 다른 요청을 지연시키는 시나리오에 대응할 수 있도록 timeout 속성을 사용해야합니다. xhr = new XMLHttpRequest(); xhr.timeout = 5000; xhr.ontimeout = timeoutFired; –

3

동시 연결 수의 정확성을 알 수 있습니다. http://www.browserscope.org/?category=network

을 그리고 불행하게도, 나는 멀티플렉싱 및/또는 다른 호스트 이름을 사용하는 것을 제외하고, 주변에 어떤 일을 못 찾았 :

당신은 최대 값이 목록을 확인할 수 있습니다.

관련 문제