使用URL重写反向代理socket.io的websocket

3
我正在尝试反向代理多个socket.io websockets,并重写URL,以便我可以拥有一个前端服务器,可以连接到多个后端tty.js实例。
例如:
http://mysite.com/server1 reverse proxies to http://server1/ which is running tty.js

http://mysite.com/server2 reverse proxies to http://server2/ which is running tty.js

对于HTTP,任何旧的代理程序都可以正常使用。但是,当我重写URL时,Websocket看起来像:

http://mysite.com/server1/socket.io/1/?t=1354135029745 -> http://server1/socket.io/1/?t=1354135029745

看起来像:

http://mysite.com/socket.io/1/?t=1354135029745

这当然是未被处理的。我假设重写发生了,因此套接字认为它的“连接”在 /socket.io/1/?t=1354135029745 而不是 /server1/socket.io/1/?t=1354135029745。

有没有一种方法可以同时进行URL重写和代理websocket?

到目前为止,我尝试过使用Varnish、node-http-proxy和Nginx来使用TCP代理模块,但我还没有弄清楚如何让它们能够正常工作。

现在我的Varnish配置看起来像:

backend backend1 {
    .host = "1.1.1.1";
    .port = "8080";
    .connect_timeout = 1s;
    .between_bytes_timeout = 60s;
    .max_connections = 800;
}

backend backend2 {
    .host = "2.2.2.2";
    .port = "8080";
    .connect_timeout = 1s;
    .between_bytes_timeout = 60s;
    .max_connections = 800;
}

sub vcl_recv {
    set req.grace = 120s
    if(req.url ~ "^/server1/") {
       set req.url = regsub(req.url, "^/server1/", "/");
       set req.backend = backend1;
       return(pipe);
    }
    if(req.url ~ "^/server2/") {
       set req.url = regsub(req.url, "^/server2/", "/");
       set req.backend = backend2;
       return(pipe);
    }
}

sub vcl_pipe {
    if(req.http.upgrade) {
        set bereq.http.upgrade = req.http.upgrade;
    } else {
        set bereq.http.connection = "close";
    }
    return(pipe);
}

我不得不省略必须的内容:

 if(req.url ~ "^/socket.io/") {
    set req.backend = backend1;
    return(pipe);
 }

自从我有了多个后端,是否可以使用node-http-proxy、Nginx或Varnish来使其工作?如果以上工具都不行,haproxy或其他什么东西能否胜任?
我的第一反应是设置自定义标头,这样当URL被重写时,它就知道应该访问哪个后端,但我不确定如何实现。
编辑1:我通过获取req.http.referer并将其添加到socket.io语句中也能够解决这个问题。
if(req.url ~ "^/socket.io/" && req.http.referer ~ "server1"){
   set req.backend = backend1;
   return(pipe);
}

然而,它似乎有点不稳定,并且似乎将socket.io恢复到xhr轮询,这并不理想,但总比没有好。

编辑2:在与几个后端进行测试后,发现一旦长轮询开始,就会破坏其余的代理。现在只要我刷新页面,反向代理就不再像以前那样工作了。
http://mysite.com/server1 -> http://server1

进行:

http://mysite.com/ -> http://server1

直到我重新加载Varnish,然后才能回去。

1个回答

0

很可能您还需要在vcl_recv()中更改Host:头:

sub vcl_recv {
    set req.grace = 120s
    if(req.url ~ "^/server1/") {
       set req.url = regsub(req.url, "^/server1/", "/");
       set req.http.host = "server1";
       set req.backend = backend1;
       return(pipe);
    }
    if(req.url ~ "^/server2/") {
       set req.url = regsub(req.url, "^/server2/", "/");
       set req.http.host = "server2";
       set req.backend = backend2;
       return(pipe);
    }
}

这应该解决了你的初始问题。

但是,在 Varnish 中使用管道也有其缺点,你可能要考虑其中最重要的一个是在第一次请求之后缺少 X-Forwarded-For 头部


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接