2012-10-23 2 views
5

최신 Chrome 브라우저를 사용하는 경우 sockjs 클라이언트를 사용하여 haproxy 뒤에있는 백엔드 서버와 통신하려고합니다. 내 로컬 호스트에서 (중간에 haproxy없이)이 작업은 정상적으로 작동합니다. 클라이언트는 websocket 프로토콜을 사용하여 메시지를 연결하고 보내고받을 수 있습니다. 예를 들면 : 나는 HAProxy로 서버에 배포되면WebSocket 핸드 셰이크가 HAProxy로 응답합니다.

conn.onopen = function() { 
    if (conn.readyState === SockJS.OPEN) { 
     conn.send("hello server"); 
     console.log("msg sent"); 
    } 
}; 

는 이상한 것은 sockjs가 ('전송 MSG'는 콘솔 로그에 나타납니다 conn.readyState === SockJS.OPEN에서와 같이), 그러나, websocket 핸드 셰이크 연결이 열려있는 생각하는 것을 어떻게 단순히 멈추고 msg는 서버에 수신되지 않습니다. 때이 종료 haproxy 뒤에 백엔드 서버를 두 번째 로그 MSG 만 나타납니다

Oct 23 09:08:25 localhost.localdomain haproxy[14121]: 129.xx.xxx.105:55000 [23/Oct/2012:09:08:24.459] public www/content 777/0/0/1/778 200 375 - - ---- 3/3/0/1/0 0/0 "GET /sockjs/info HTTP/1.1" 
Oct 23 09:10:54 localhost.localdomain haproxy[14121]: 129.xx.xxx.105:55015 [23/Oct/2012:09:08:25.398] public www/content 0/0/0/1/149017 101 147 - - CD-- 4/4/0/0/0 0/0 "GET /sockjs/478/kyi342s8/websocket HTTP/1.1" 

공지 것을 : 아래는 내가 haproxy 로그에 표시되는 내용입니다. 종료 전에는 로그에 오류가 없지만 websocket 핸드 셰이크가 완료되지 않고 서버에서 아무런 메시지도 수신하지 않습니다.

Request URL:ws://www.mysite.com/sockjs/478/kyi342s8/websocket 
Request Method:GET 
Status Code:101 Switching Protocols 

Request Headers 
Connection:Upgrade 
Host:www.mysite.com 
Origin:http://www.mysite.com 
Sec-WebSocket-Extensions:x-webkit-deflate-frame 
Sec-WebSocket-Key:TFEIKYhlqWWBZKlXzXAuWQ== 
Sec-WebSocket-Version:13 
Upgrade:websocket 
(Key3):00:00:00:00:00:00:00:00 

Response Headers 
Connection:Upgrade 
Sec-WebSocket-Accept:D+s3va02KH6QTso24ywcdxcfDgM= 
Upgrade:websocket 
(Challenge Response):00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 

과의 네트워크 탭에서 websocket 오브젝트 쇼 '보류'모두 '형'과 '시간 지연'네트워크 탭에서, 나는 다음을 참조 크롬의 개발자 도구를 사용하여

, 개발자 도구. 이런 일이 왜

global 
     log 127.0.0.1 local1 info 
     log 127.0.0.1 local1 notice 
     #log loghost local0 info 
     maxconn 4096 
     chroot /usr/share/haproxy 
     uid 99 
     gid 99 
     daemon 
     #debug 
     #quiet 

defaults 
     log    global 
     mode   http 
     option   httplog 
     option   dontlognull 
     retries   3 
     option   redispatch 
     maxconn   500 
     timeout connect 6s 

frontend public 
     mode http 
     bind *:80 
     timeout client 300s 
     option http-server-close 
     #option   http-pretend-keepalive 
     # define ACLs 
     acl host_static hdr_beg(host) -i static. data. 
     acl host_www hdr_beg(host) -i www. 
     acl url_static path_end .ico .txt .pdf .png .jpg .css .js .csv 
     acl is_stats path_beg /haproxy/stats 
     # define rules 
     use_backend nginx if host_static or host_www url_static 
     use_backend stats if is_stats 
     default_backend www 

backend nginx 
     timeout server 20s 
     server nginx 127.0.0.1:8484 

backend stats 
     stats enable 
     stats uri /haproxy/stats 

backend www 
     timeout server 300s 
     option forwardfor 
     #no option httpclose 
     option http-server-close 
     server sockcontent 127.0.0.1:8080 

사람이 알고 있나요 :

마지막으로,이 내 haproxy 설정은 (버전 1.4.22)입니까? 일부 haproxy 설정 또는 서버의 일부 일반적인 네트워크 설정 (예 : iptables) 때문입니까?

P. http-pretend-keepalivehaproxy에 사용하려고 시도했지만 작동하지 않습니다.

답변

1

대부분의 경우, 당신은 당신의 네트워크에서 투명 방화벽이 있으며 그런 경우 확인하려면 포트 80

에가는 웹 소켓 연결을 망쳐 놨 :

  1. 만들기가 다른 포트에서 듣고한다면, 시도 haproxy 그것은 일하기 시작했습니다.
  2. 네트워크 외부의 서비스에 액세스 해보십시오.

작동이 시작되면 네트워크에 문제가있는 것입니다.

불행히도 SockJS는 클라이언트가 연결되어 있다고 생각하지만 연결이 실제로 이루어지지 않았기 때문에이 경우 대체 전송을 사용하지 않습니다.

가능한 해결책 : haproxy가 웹 트래픽의 경우 포트 80에서, SockJS 트래픽의 경우 다른 포트에서 수신 대기하도록 설정하십시오. 이렇게하면 투명한 HTTP 프록시가 websocket 연결을 엉망으로 만들지 않습니다.

1

나는이 사건을 이미 경험했다. 나는 그것이 어떤 서버인지 기억하지 못하지만 WebSocket 사양을 완전히 준수하지는 못했다. 실제로 "업그레이드"토큰이 필요하고 (다행스럽게도) 다른 토큰을 거부하도록 제안하지 않는다는 내용의 "업그레이드"토큰과 함께 Connection 헤더에 "닫기"토큰이 있기 때문에 실패했습니다.

"옵션 http-pretend-keep-alive"를 사용하면 이론적으로는 정상적으로 작동합니다. 적어도 그것은 나를 위해했다. 하지만 여기에는 다른 문제가있을 수 있습니다.

2

마찬가지로 @ 잼이 말하길, 방화벽이 잘못 작동하는 것은 잘못입니다. 어떤 사람들은 예를 들어 포티게이트가 원인이라고 말합니다.

더 많은 토론 : SSL을 통한 https://github.com/sockjs/sockjs-client/issues/94

봉사 SockJS 문제를 해결할 것으로 보인다.