Với trình duyệt Chrome mới nhất, tôi đang cố gắng sử dụng sockjs
ứng dụng khách để liên lạc với máy chủ phụ trợ phía sau haproxy
. Trên localhost của tôi (không có haproxy
ở giữa), điều này hoạt động tốt - khách hàng có thể kết nối, gửi và nhận tin nhắn bằng giao thức websocket
. Ví dụ:Websocket handshake treo cứng với HAProxy
conn.onopen = function() {
if (conn.readyState === SockJS.OPEN) {
conn.send("hello server");
console.log("msg sent");
}
};
Khi tôi triển khai nó trên máy chủ với HAProxy
, điều kỳ lạ xảy ra mà sockjs
nghĩ kết nối được mở (như trong conn.readyState === SockJS.OPEN
và 'msg gửi' xuất hiện trong giao diện điều khiển log), tuy nhiên, websocket
bắt tay chỉ đơn giản là treo và msg là không bao giờ nhận được bởi máy chủ. Dưới đây là những gì tôi nhìn thấy trong log haproxy
:
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"
Chú ý rằng các bản ghi thứ hai msg chỉ xuất hiện khi tôi tắt máy tính, máy chủ backend đằng sau haproxy
. Trước khi tắt máy, không có lỗi trong nhật ký nhưng việc bắt tay websocket không hoàn thành và không nhận được tin nhắn từ máy chủ.
Sử dụng công cụ phát triển của Chrome, tại tab Network, tôi thấy như sau:
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
Và cả hai 'Loại' và 'Thời gian trễ' của đối tượng cho thấy websocket
'chờ' dưới tab mạng lưới Những công cụ phát triển.
Cuối cùng, đây là haproxy
cấu hình của tôi (phiên bản 1.4.22):
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
Có ai biết tại sao điều này đang xảy ra? Có phải do một số cấu hình haproxy
hoặc thậm chí một số cài đặt mạng chung của máy chủ (ví dụ: iptables
)?
P.S. Tôi đã thử kích hoạt http-pretend-keepalive
trong haproxy
, nhưng nó không hoạt động.