我正在开发一个 node.js 应用程序,使用 express 提供内容和 socket.io 用于 websocket 通信。设置工作正常,但现在我也希望能够通过 SSL 访问 websocket。我认为使用 nginx(我们已经用于其他东西)作为代理是一个好主意,并像这样配置它:
upstream nodejs {
server 127.0.0.1:8080;
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
server_name _;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://nodejs;
proxy_redirect off;
}
}
node.js 服务器是这样设置的:
var express = require('express'),
app = express();
// some app configuration that I don't think matters
server = http.createServer(app).listen(8080);
var io = require('socket.io').listen(server);
io.configure(function() {
io.set('match original protocol', true);
io.set('log level', 0);
io.set('store', redisStore); // creation of redisStore not shown
}
nginx 和 node.js 都在一个 Vagrant 盒子中运行,该盒子将端口 443(nginx 监听)转发到主机系统上的端口 4443。
使用此设置,导航到http://localhost:4443
(使用 Firefox 23)使我可以访问 Express 提供的文件,但是当 socket.io 尝试连接到套接字时,它会引发以下错误:
Blocked loading mixed active content "http://localhost:4443/socket.io/1/?t=1376058430540"
这个结果很明显,因为它试图通过 HTTP 从 HTTPS 页面内部加载 JS 文件,而 Firefox 不允许这样做。问题是它为什么首先这样做。
Socket.io 尝试确定使用哪个协议来访问网页,并在上述 URL 的构造中使用相同的协议。在这种情况下,它认为它是通过 HTTP 访问的,这可能是被代理的结果。但是,据我了解,在 socket.io 配置中设置match original protocol
为true
应该在这种情况下有所帮助,但在我的情况下却没有。
我在这里找到了许多关于 websocket 代理的问题和答案,但没有一个涉及这个特定问题。所以我几乎束手无策,非常感谢一些建议。