Node.js &引用;无法获取;从Nginx到express.js上的socket.io的反向代理

Node.js &引用;无法获取;从Nginx到express.js上的socket.io的反向代理,node.js,express,nginx,socket.io,Node.js,Express,Nginx,Socket.io,我已经通过私有网络让Node.js通过Nginx在两台Ubuntu14.04服务器上工作(Node.js在myappserver上-可通过私有IP myprivatewebserver访问,也可通过mypublicappserver公开-和mywebserver上的Nginx)。在这一点之前,一切都正常-我可以访问myprivateappserver:3000上的node.js应用程序,通过Nginx访问 但是,当我尝试在express.js上运行in-socket.io时,当我直接访问它()时

我已经通过私有网络让Node.js通过Nginx在两台Ubuntu14.04服务器上工作(Node.js在myappserver上-可通过私有IP myprivatewebserver访问,也可通过mypublicappserver公开-和mywebserver上的Nginx)。在这一点之前,一切都正常-我可以访问myprivateappserver:3000上的node.js应用程序,通过Nginx访问

但是,当我尝试在express.js上运行in-socket.io时,当我直接访问它()时,它会起作用,但当我尝试通过我的Nginx代理()访问它时,我会在浏览器和firebug控制台中得到“Cannot get/node” “网络错误:找不到404-”

如果我从mywebserver中获取curl,则可以从socket.io应用程序中获取index.html

My/etc/nginx/sites available/default包含:

location /node{
proxy_pass http://myprivateappserver:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
我的index.js是:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});
我的index.html是:

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
      var socket = io();
      $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
      });
      socket.on('chat message', function(msg){
        $('#messages').append($('<li>').text(msg));
      });
    </script>
  </body>
</html>

Socket.IO聊天
*{边距:0;填充:0;框大小:边框框;}
正文{字体:13px Helvetica,Arial;}
表单{background:#000;填充:3px;位置:固定;底部:0;宽度:100%;}
表单输入{边框:0;填充:10px;宽度:90%;右边距:5%;}
窗体按钮{宽度:9%;背景:rgb(130224255);边框:无;填充:10px;}
#消息{列表样式类型:无;边距:0;填充:0;}
#消息li{padding:5px 10px;}
#留言李:第n个孩子(奇数){背景:#eee;}
    发送 var socket=io(); $('form')。提交(函数(){ emit('chat message',$('#m').val()); $('m').val(''); 返回false; }); socket.on('chat message',函数(msg){ $(“#消息”).append($(“
  • ”).text(msg)); });

  • 这是我第一次涉足nginx/node/express/socket(我通常是Apache/CakePHP人)因此,我可能错过了一些非常简单的东西,但也非常感谢关于如何调试出错的任何指针这是因为SocketIO默认使用
    /socket.io
    路径,所以您需要配置Nginx,以便它不仅代理
    /node
    请求,而且代理
    /socket.io

    location ~ ^/(node|socket\.io) {
        #your proxy directives
    }
    
    (顺便说一句,您似乎有打字错误:您编写了
    proxypass
    ,但正确的形式是
    proxy\u-pass
    。其他
    proxy
    指令也是如此)

    您还需要在NodeJS服务器文件中再执行一次编辑。替换:

    app.get('/', function(req, res){
    
    与:

    现在应该可以了


    这不是唯一的解决方案。您也可以在Nginx配置中进行一些更改,但上面描述的解决方案对我来说似乎是最简单的。祝您好运!

    Good aswer by Guilly。我想补充一点,如果您使用sub_筛选器,您不必调整node.js应用程序。您的Nginx必须使用该模块编译

    location ~ ^/(node|socket\.io) {
        #your proxy directives
        sub_filter /node /;
    }
    


    在没有“^”和“\“招牌。

    非常感谢@好奇。这将花费我很长很长的时间来为自己解决问题——我不知道代理地址与它代理的应用程序之间有多么相互关联。我重新插入了在粘贴时从代理通行证等指令中删除的下划线,以免混淆到达此页面的其他人。再次感谢。@theotherdy欢迎您)代理时有多种转换URL的选项,您可以阅读更多。下划线呢?您做了一件好事,但在
    $httpupgrade
    变量中忽略了下划线。祝你好运:)我想我需要读一些Nginx手册。在缺少的下划线上有很好的标记-现在也添加了该下划线。再次感谢如果有其他人遵循此线程,我今天上午大部分时间都在意识到,当我在CakePHP应用程序中(该应用程序由提供服务)尝试与以下对象建立连接:var socket=io(');这是正确的代理并通过连接到,但是,尽管存在连接,Socket.io认为我是说我希望通信位于“节点”命名空间中,因此emit不起作用!但是,更改为:var nsp=io.of('/node'),然后改为nsp.on('connection',function(socket){等,它就可以工作了!请也帮助我..我不想让请求传递到我的应用程序。
    location ~ ^/(node|socket\.io) {
        #your proxy directives
        sub_filter /node /;
    }
    
    location ~ /(node|socket.io)  {
    .......
    
    }