nodejs https socket.io 连接失败

nginx 改用 https 之后原有 express 中的 socket.io 请求被拒绝

https 是在 nginx 一层做的, nodejs 还是 http

代码大致是这个样子的:

www

var server = http.createServer(app).listen(3000);
var io = require('../tool/SocketBiz')(server);

SocketBiz

function Socket(Server) {
  var io = require('socket.io')(Server)
  io.sockets.on('connection', function (socket) {
    socket.on('join', function(room) {
      console.log('加入', room)
      socket.join(room)
    })
  })  
}

module.exports = Socket; 

html

<script src="xxx/socket.io.js"></script>
...

var socket = io('xxx.xxx.xxx.xxx:3000')

nginx

upstream nodejs__upstream {
    server 127.0.0.1:3000;
    keepalive 64;
}
server {
    listen 443 ssl;
    ssl_certificate "/etc/nginx/cert/ca.pem";
    ssl_certificate_key "/etc/nginx/cert/ca.key";
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_timeout 5m;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    server_name www.xxxx.com xxxx.com;
    access_log /root/nginx.log;
    location / {
        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_http_version 1.1;
        proxy_pass         http://nodejs__upstream;
    }
}
server {
   listen 80;
   server_name www.xxxx.com xxxx.com;
   return 301 https://$server_name$request_uri;
}

其他部分都访问正常, 只有 socket 部分是连接失败, 错误是:

(failed) net::ERR_INSECURE_RESPONSE

是因为 server 那边是 http 的 server, 请求连接的是 https 的 server.

该如何处理呢


最终处理:

html

var socket = io()

nginx

upstream nodejs__upstream {
    server 127.0.0.1:3000;
    keepalive 64;
}
server {
    listen 443 ssl;
    ssl_certificate "/etc/nginx/cert/ca.pem";
    ssl_certificate_key "/etc/nginx/cert/ca.key";
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_session_timeout 5m;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    server_name www.xxxx.com xxxx.com;
    access_log /root/nginx.log;
    location / {
        proxy_pass http://nodejs__upstream;
        proxy_set_header   X-Real-IP            $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header   X-NginX-Proxy    true;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}
server {
   listen 80;
   server_name www.xxxx.com xxxx.com;
   return 301 https://$server_name$request_uri;
}

确实 nginx 处理 websocket 需要特殊的配置,传送门

其实本来就调通了,中间做了一些实验,自己又把自己绊倒了。

完结,谢谢热心人们。

阅读 7.8k
1 个回答

试试吧来自这里

location /socket.io/ {
        //此处改为 socket.io 后端的 ip 和端口即可
        proxy_pass http://127.0.0.1:3000;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题