javascript - Socket.io 未通过 Cloudflare/Nginx 断开连接

标签 javascript node.js nginx socket.io cloudflare

我有一个小型 Web 应用程序,它由 Express.js 提供服务,并通过 Socket.io 连接到后端。为了公开,我使用 Nginx 作为反向代理,然后在最前面使用 Cloudflare。该应用程序依赖于关闭或重新加载时触发的 disconnect 事件来跟踪在线用户等。当通过 Nginx 和 Cloudflare 时,断开连接事件永远不会在后端触发。在本地开发时确实如此。

这是我的 Nginx 配置文件:

server {
    listen 80;
    server_name colab.gq;
    server_name www.colab.gq;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header X-Forwarded-For $remote_addr;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/colab.gq/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/colab.gq/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

这是我的服务器端代码片段:

io.on('connection', (socket) => {
  // Stuff here

  socket.on('disconnect', () => {
    console.log('disconnected!')
    // Stuff that relies on the disconnect event
  })
})

当用户关闭选项卡或重新加载页面时,断开连接事件应该触发,但通过 Nginx 和 Cloudflare 传递连接时永远不会触发。预先感谢您的帮助!

更新:似乎在重新加载/关闭断开事件几秒钟后终于注册。

最佳答案

您必须将升级 header 添加到 nginx 配置中的套接字 io 路径,如下所示,

    location ~* \.io {
      .. your configuration

      proxy_pass http://localhost:3000;
      proxy_redirect off;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }
<小时/>

既然您要求扩展答案,您可能已经知道的第一件事是 socket.io 是一个在底层使用 Websockets 协议(protocol)的协议(protocol)(因此两者是相同的)。作为标准,Websockets 协议(protocol)和 HTTP 协议(protocol)都监听相同的端口 80 或 443。默认协议(protocol)是 HTTP,如果用户想要使用 Websockets 协议(protocol),他/她必须发送从 HTTP 到 WS 协议(protocol)的升级请求,并且有一些关键身份验证和步骤。

这就是为什么您需要将它们放入 nginx 配置中。

引用this如果您需要有关协议(protocol)升级机制的更多信息。

尽管在我看来,这并不完全复制 this问题,我觉得有义务给予@Paulo学分即使不被接受,也要提供完美的答案。

关于javascript - Socket.io 未通过 Cloudflare/Nginx 断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55325180/

相关文章:

javascript - 也许是 JavaScript 中的 monad

node.js - 错误: FAILED_PRECONDITION: no matching index found.推荐索引为:

nginx - node.js 准备好用于生产了吗?

linux - 配置 NGINX 时如何使用环境变量作为前缀路径?

javascript - 如何处理 Laravel 上包含 Carbon 日期的模型的 JSON 响应?

javascript - 如何使 div 成为设备屏幕高度 css 的 10%

javascript - 基于 req.user 验证用户是否是管理员是否安全?

http - nginx 和带有代理传递的尾部斜线

javascript - 生态错误消息 : Unexpected 'INDENT' in Windows

c++ - 实时音频(发送和接收)的好库?