【问题标题】:Socket.io disconnects on http requestSocket.io 在 http 请求上断开连接
【发布时间】:2018-03-08 23:30:34
【问题描述】:

我正在 AWS EC2 实例上为我的 node.js 应用程序运行 nginx。我想使用 websockets (socket.io) 和正常的 http 请求/响应。我的问题是,每当我从移动设备到服务器的活动套接字连接并尝试发出正常的 http 请求时,都会调用移动设备的 socket.io 错误函数并显示消息“502 Bad Gateway”。

只有套接字有效。只有普通的 http 请求也可以。

我发现这个问题是在我将 nginx 设置为仅使用 https 之后发生的。

这是我在 /sites-enabled /sites-available 中的 nginx 配置:

server {
    listen 80;
    listen 443 ssl;

    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;

    if ($scheme != "https") {
        rewrite ^ https://$host$request_uri? permanent;
    }

    location / {
        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;
    }
}

Nginx 错误日志:

[error] 14117#14117: *50 upstream prematurely closed connection while reading response header from upstream, client: 78.94.9.226, server: example.com, request: "GET /socket.io/?transport=polling&b64=1&sid=rgXMQhL6mbSET8ktAAAA HTTP/1.1", upstream: "http://127.0.0.1:3000/socket.io/?transport=polling&b64=1&sid=rgXMQhL6mbSET8ktAAAA", host: "example.com"

iOS 错误日志:

LOG SocketIOClient: Handling event: error with data: ["Got unknown error from server <html>\r\n<head><title>502 Bad Gateway</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>502 Bad Gateway</h1></center>\r\n<hr><center>nginx/1.10.3 (Ubuntu)</center>\r\n</body>\r\n</html>\r\n"]

如果您需要更多信息,请告诉我!

【问题讨论】:

    标签: node.js nginx amazon-ec2 socket.io


    【解决方案1】:

    将您的 nginx 配置更改为两个块

    server {
        listen 80;
        listen 443 ssl;
    
        server_name example.com www.example.com;
    
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
    
        if ($scheme != "https") {
            rewrite ^ https://$host$request_uri? permanent;
        }
    
        location /socket.io {
            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;
        }
    
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host;
        }
    }
    

    您只想升级socket.io 的连接,而不是其他网址

    【讨论】:

    • 感谢您的帮助!我自己解决了这个问题。
    • 请分享解决方案作为答案
    • 我确实在几秒钟前分享了解决方案
    【解决方案2】:

    我自己解决了这个问题。这真是一个愚蠢的问题。我在我的 node.js 服务器文件夹中创建了一个名为 access.log 的文件,并告诉摩根记录器写入该文件。我忘记的是,只要服务器文件夹内的代码发生更改,我就会使用 PM2 重新启动服务器。所以PM2每次我发出http请求并且socket断开时都会重启服务器。

    【讨论】:

    • 感谢分享解决方案。我猜 PM2 会使用参数来观察 .js、.css 等的变化吗?如果是这样,您应该使用它
    • 我注意到 PM2 自己记录 http 请求 + stdout/stderr,所以我禁止 morgan 写入文件。 PM2 日志足以满足我的需求。
    • 我也面临同样的问题。可以分享一下代码或资源吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2015-09-08
    • 2012-11-09
    相关资源
    最近更新 更多