With the latest Chrome browser, I am trying to use sockjs
client to communicate with a backend server which is behind haproxy
. On my localhost (without haproxy
in the middle), this is working fine - the client can connect, send and receive messages using websocket
protocol. For example:
conn.onopen = function() {
if (conn.readyState === SockJS.OPEN) {
conn.send("hello server");
console.log("msg sent");
}
};
Once I deploy it on the server with HAProxy
, strange thing happens that sockjs
thinks the connection is open (as in conn.readyState === SockJS.OPEN
and 'msg sent' appears in the console log), however, websocket
handshake simply hangs and msg is never received by the server. Below is what I see in the haproxy
log:
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"
Notice that the second log msg only appears when I shutdown the backend server behind haproxy
. Before the shutdown, no error in the log but the websocket handshake doesn't complete and no msg is received by the server.
Using the Chrome's developer tools, in the Network tab, I see the following:
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
And both 'Type' and 'Time Latency' of the websocket
object show 'Pending' under the network tab of developer tools.
Finally, this is my haproxy
config (version 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
Does anyone know why this is happening? Is it due to some haproxy
config, or even some general network settings of the server (e.g iptables
)?
P.S. I've tried enabling http-pretend-keepalive
in haproxy
, but it does not work.
Like @Joes said, it's a fault of misbehaving firewalls. Some say that for example FortiGate causes that.
More discussion: https://github.com/sockjs/sockjs-client/issues/94
Serving SockJS over SSL seems to solve the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With