nginx代理websocket写法问题(使用了socket.io)

问题很困扰,先说问题背景:

我在尝试一个非常简单的websocket应用(一个同步画板工具,移动端有效http://draw.10000h.top/canvas... )

然后后来打算用nginx配置websocket代理,由于我的websocket和nodejs服务用的不是一个端口,但是是写在一个app.js中了,因此我一开始这样配置:

upstream canvas {
      server 127.0.0.1:10002;
}

upstream websocket_canvas {
      server 127.0.0.1:10003;
}

server {
      listen 80;
      server_name draw.10000h.top;

      location /socket.io {
            proxy_pass http://websocket_canvas/socket.io;

            proxy_http_version 1.1;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_cache_bypass: $http_upgrade;

      }

      location / {
            proxy_pass http://canvas;
      }

      gzip on;
      gzip_min_length 1k;
      gzip_buffers 4 8k;
      gzip_http_version 1.1;
      gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;

}

location /socket.io这一部分的proxy_pass自己也尝试过用http://websocket_canvas/或者直接把地址写在这等等。。。

前端链接的话这样:io.connect('http://draw.10000h.top/socket.io');

后端:var io=require("socket.io").listen(10003); //start

不报任何错误,抓包的话也正常(有一个101的pending链接),但是这样写就是失败的。。。

但是我把websocket的代理单独配置出来,像这样:

server {
      listen 80;
      server_name socket.10000h.top;

      location /{
            proxy_pass http://127.0.0.1:10003;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
      }

}

然后var socket = io.connect('http://socket.10000h.top');这样就能成功。

为什么代理配置在根域名下就成功了?上一种方式为何静默失败呢?

内容有点啰嗦..请各路大神帮忙看下...谢谢

阅读 11k
2 个回答

官方文档的一句话

其实我也不清楚是不是这个问题, 它会默认加一个path,而不用你connect指定,除非你使用Path()方法传给它

弄了一个下午, 终于能访问上 websocket 了

最重要的一点是要在 location中的 proxy_pass 最后加上 / 斜杠

比如下面的例子中 proxy_pass http://echo.websocket.org/; 最后要有个斜杠

    location /socket.io/ {
        proxy_pass http://echo.websocket.org/;    
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

原因是: nginx 配置 proxy_pass URL末尾加与不加/(斜线)的是有区别的

不加斜杠则访问

http://echo.websocket.org/socket.io

而加了斜杠之后, 实际访问会减去 location 的path

http://echo.websocket.org/

我的完整配置如下, 可以在 http://www.websocket.org/echo... 上面测试

server {
    listen 80;
    server_name websocket.giraffe-tree.com;
    location /socket.io/ {
        proxy_pass http://echo.websocket.org/;    
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

    location /xx {
        proxy_pass http://echo.websocket.org/;    
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        #proxy_set_header    Host $http_host;
        proxy_set_header    X-Real-IP $remote_addr;

    }

    location / {
        proxy_pass http://echo.websocket.org;    
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }
}

另外, 我在测试的时候还加上 proxy_set_header Host $http_host; , 但奇怪的是加上去之后就不能访问了

这个问题, 大家有兴趣可以测试下这个问题, 有了解原理的麻烦回复下我, 非常感谢!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题