从Nginx到express.js上的socket.io反向代理上的“不能GET”

我已经遵循本教程 ,通过专用networking(Node.js位于myappserver上 – 可通过私有IP myprivatewebserver访问,公开地通过mypublicappserver – 以及mywebserver上的Nginx),让Node.js通过Nginx在两台Ubuntu 14.04服务器上工作。 一切工作正常直到这一点 – 我可以通过访问http:// mywebserver /节点访问通过Nginx的myprivateappserver:3000代理上的node.js应用程序。

但是,当我尝试运行express.js上的socket.io 聊天应用程序时,它直接访问它( http:// mypublicappserver:3000 ),但是,当我尝试通过我的Nginx代理( http :// mywebserver / node ),我在浏览器和萤火虫控制台中看到“Can not GET / node”“NetworkError:404 Not Found – http:// mywebserver / node ”。

如果我从mywebserver curl http:// myprivateappserver:3000 ,我从我的socket.io应用程序获得index.html罚款。

我的/ 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> 

这是我第一次进入nginx / node / express / socket(我通常是一个Apache / CakePHP的人),所以我可能会错过一些非常简单的东西,但也非常感谢任何指针如何debugging出了什么问题

这是因为SocketIO默认使用/socket.io路径,因此您需要配置Nginx,以便它不仅可以代理/node请求,而且还可以/socket.io代理:

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

(顺便说一下,它看起来像你有错别字:你写了proxypass ,但正确的形式是proxy_pass 。同样的其他proxy指令)

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

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

有:

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

现在它应该工作。

这不是唯一的解决方案。 你也可以在Nginx配置中修改一下SocketIO的路径 ,但是上面介绍的解决方案对我来说似乎是最简单的。 祝你好运!

好奇的好。 我想补充一点,如果使用sub_filter,则不必调整node.js应用程序。 你的nginx必须使用该模块进行编译。

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