我在尝试配置的 ubuntu 服务器上使用 haproxy 正确路由 socket.io websocket 握手时遇到了很大的问题。我在这里和网上都读了很多,但我似乎找不到一个确凿的解决方案。我必须实现的目标非常复杂。我有不止一个 nodejs 在同一台服务器上运行,每个都在不同的端口上,但我必须能够从浏览器的端口 80 上访问所有这些(客户端防火墙问题)。我设法实现的是用 haproxy 重写
http://HOST/8081/
至
http://HOST:8081/
在后端,以便每个请求都将路由到正确的 nodejs istance。我现在遇到了套接字问题,因为要让 haproxy 重写每个请求,我必须使用 httpclose 作为选项,但这会使 websockets 失败。搜索我找到了一种解决方法,将以 /socket.io 或 /node 开头的请求路由到具有正确端口但具有不同选项的同一后端。这行得通,但是现在所有的 websockets 请求都链接到同一个 nodejs istance,这显然是一个问题,因为所有客户端现在都连接到一个服务器。我已经尽我所能创建和 acl 将 websockets 发送到正确的服务器,但我在请求中找不到任何东西来路由它们。这是我设法实现的最后一个配置,通过这个配置,websocket 请求被路由到正确的服务器,
WebSocket 连接到 ws://HOST/socket.io/1/websocket/Wra1vIqoPcTqBNkRLTif' 失败:意外响应代码:503
global
log 127.0.0.1 local0 debug
maxconn 4096
user haproxy
group haproxy
daemon
defaults
log global
mode http
# httpclose is necessary otherwise haproxy will rewrite only the first request of the session
option httpclose
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
frontend http
bind :80
option forwardfor
acl is_socket_io path_beg /node
acl is_socket_io path_beg /socket.io
#use_backend socket_io if is_socket_io
acl myacl_rewrite0 hdr(host) -i HOST
acl myacl_path0 path_dir -i 8081
acl myacl_referer0 hdr_beg(referer) http://HOST/8081/
use_backend socket_io_8081 if is_socket_io myacl_referer0
use_backend mysrv_rewrite0 if myacl_rewrite0 myacl_path0
acl myacl_rewrite1 hdr(host) -i HOST
acl myacl_path1 path_dir -i 8090
acl myacl_referer0 hdr_beg(referer) http://HOST/8090/
use_backend socket_io_8090 if is_socket_io myacl_referer0
use_backend mysrv_rewrite1 if myacl_rewrite1 myacl_path1
backend mysrv_rewrite0
reqirep ^([^\ :]*)\ /8081/(.*) \1\ /\2
server myorigin_rewrite0 127.0.0.1:8081
backend mysrv_rewrite1
reqirep ^([^\ :]*)\ /8090/(.*) \1\ /\2
server myorigin_rewrite1 127.0.0.1:8090
backend socket_io_8081
mode http
option httplog
# long timeout
timeout server 86400000
# check frequently to allow restarting
# the node backend
timeout check 1s
# add X-Forwarded-For
option forwardfor
# Do not use httpclose (= client and server
# connections get closed), since it will close
# Websockets connections
no option httpclose
# Use "option http-server-close" to preserve
# client persistent connections while handling
# every incoming request individually, dispatching
# them one after another to servers, in HTTP close mode
option http-server-close
option forceclose
server node1 127.0.0.1:8081 maxconn 2000 check
backend socket_io_8090
mode http
option httplog
# long timeout
timeout server 86400000
# check frequently to allow restarting
# the node backend
timeout check 1s
# add X-Forwarded-For
option forwardfor
# Do not use httpclose (= client and server
# connections get closed), since it will close
# Websockets connections
no option httpclose
# Use "option http-server-close" to preserve
# client persistent connections while handling
# every incoming request individually, dispatching
# them one after another to servers, in HTTP close mode
option http-server-close
option forceclose
server node2 127.0.0.1:8090 maxconn 2000 check
忘了说,我有
socket.io version 0.9.11
haproxy version 1.4.18