使用 nginx 自动代理 WebSockets 端点

使用 nginx 自动代理 WebSockets 端点

我正在尝试为 Web 应用程序(特别是 JupyterLab,但这个问题是通用的)编写 Nginx 反向代理配置。

Web 应用程序在多个不相交的 URL 层次结构中使用多个 WebSockets 端点。例如,

  • /jupyter/api/yjs/...
  • /jupyter/terminals/...
  • /jupyter/api/collaboration/room/...
  • (和别的)

都是 WebSockets 端点。我写了一个临时配置,如下所示:

                location /jupyter/ {
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_set_header Host $host;
                        client_max_body_size 0;
                        proxy_pass http://jupyter;
                }

                location ~ ^/jupyter/api/yjs/ {
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                        proxy_set_header Host $host;
                        proxy_http_version 1.1;
                        proxy_set_header Upgrade $http_upgrade;
                        proxy_set_header Connection "Upgrade";
                        proxy_pass http://jupyter;
                }

                <repeated sections for other WebSockets endpoints>

但是,完整的 WebSockets 端点列表并没有记录下来。我尝试分析 nginx 和应用程序日志,推断哪些 URL 需要代理为 WebSockets,但这显然不可靠。


有没有办法编写一个 nginx 配置,以便将所有传入的 WebSocket 请求代理为 WebSockets,并将纯 HTTP 请求代理为纯 HTTP,无需在 nginx 配置中对 WebSockets 位置进行硬编码

答案1

我发现使用 web-ui 应用程序管理反向代理更容易nginx-proxy-manager。并且我在创建代理主机时发现了一个启用的选项websockets support。如果您有兴趣使用 nginxproxymanager。您可以使用此应用程序轻松地将所有传入的 WebSockets 请求代理为 WebSockets。

在此处输入图片描述

答案2

这可以通过使用映射变量和一些有关 WebSocket 的知识来实现​​。

WebSocket 连接是使用带有两个标头的 HTTP 1.1 请求发起的:Connection: UpgradeUpgrade: WebSocket,两者都是逐跳的(因此通常不使用代理)。

我们只需在后端连接上启用 HTTP 1.1,并使用和proxy_http_version 1.1代理两个标头。但是,我们仍需要在常规(非 WebSocket)请求上提供,以与 NGINX 默认值保持一致。因此:proxy_set_header Connection $http_connectionproxy_set_header Upgrade $http_upgradeConnection: close

# in http context
map $http_upgrade $proxy_connection {
        ''      'close';
        default 'upgrade';
}

<...>

# in server context
location /jupyter/ {
        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Connection $proxy_connection;
        proxy_set_header Upgrade $http_upgrade;

        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
        client_max_body_size 0;

        proxy_pass http://jupyter;
}

相关内容