【问题标题】:WebSocket connection to "wss" sockjs-node failed for CRA and nginx reverse proxyCRA 和 nginx 反向代理与“wss”sockjs-node 的 WebSocket 连接失败
【发布时间】:2021-10-03 04:48:28
【问题描述】:

这是我的开发设置:

  • 我在 docker 内部使用 create-react-app 创建了一个 React 项目
  • 我在docker-compose.yml 文件中使用npm start 以通常的方式提供服务
  • 现在可以在我的本地主机上使用http://localhost:3000 访问它
  • 为了模拟服务器条件,我设置了 nginx 和本地 DNS
  • /etc/hosts 我添加127.0.0.1 domain.local
  • 使用mkcert 我制作了本地有效的证书
  • nginx我创建如下配置文件:
server {
    listen 80;
    server_name domain.local;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name domain.local;

    ssl_certificate /Temp/Project/Certificate.pem;
    ssl_certificate_key /Temp/Project/Key.pem;

    location / {
        proxy_pass http://localhost:3000;
    }
}

问题是当我转到https://domain.local 而不是http://localhost:3000 时,我失去了热重载,并且我在控制台中看到了这个错误:

webpackHotDevClient.js:60 WebSocket 连接到“wss://domain.local/sockjs-node”失败:
../../Project/node_modules/react-dev-utils/webpackHotDevClient.js @ webpackHotDevClient.js:60
webpack_require @ bootstrap:851
fn@bootstrap:150
1@index.js:7
webpack_require@bootstrap:851
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(匿名)@main.chunk.js:1
webpackHotDevClient.js:76 开发服务器已断开连接。
必要时刷新页面。

我该如何解决这个问题?

【问题讨论】:

  • 在服务器部署中,我根本不希望看到 Webpack 开发服务器; npm run build您的应用程序到静态文件并直接从 Nginx 容器提供它们。
  • 我不在服务器上@DavidMaze,你为什么这么认为?我在本地计算机上进行开发。第一行说这是我的开发设置
  • 你可以在没有 Docker 的情况下使用 Node 吗?我在看“模拟服务器条件,我设置了 nginx”要点;在那种环境中,您将没有开发服务器。
  • @DavidMaze,感谢您的回复。我知道我可以不用docker直接使用node。但是 docker 是我们技术栈的一部分,我们在任何地方都使用它,我们不会在本地笔记本电脑上安装 node、laravel、django 或 .net。我们只在容器内编码。

标签: node.js reactjs docker nginx


【解决方案1】:

我也在使用代理。所以问题是如何在 NGinx 中设置你的 websocket 连接。

... 包括“升级”和“连接”在内的逐跳标头不会从客户端传递到代理服务器,因此为了让代理服务器了解客户端将协议切换到 WebSocket 的意图,这些标头必须显式传递:

location /sockjs-node {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

他们recommend doing 有点长。

我在前面的示例中为您放置了localhost:3000,但我更喜欢使用单独的upstream 指令,以免混淆上游和地址。所以完整的例子(在http 指令内)将是:

upstream front {
    server localhost:3000;
}

map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 80;
    server_name domain.local;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name domain.local;

    ssl_certificate /Temp/Project/Certificate.pem;
    ssl_certificate_key /Temp/Project/Key.pem;

    location / {
        proxy_pass http://front;
    }

    location /sockjs-node {
        proxy_pass http://front;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
    }
}

不过,还没有使用 cert`s 检查您的示例。

【讨论】:

  • 请注意,如果您使用 Docker(比如 docker-compose)并且 NGinx 也在 docker 内部,您不需要直接暴露前端端口,也不需要使用 localhost一点也不。您将使用来自 docker-compose 的内部主机名,唯一暴露的端口必须是代理之一
  • > 默认情况下,如果代理服务器在 60 秒内没有传输任何数据,连接将被关闭。可以使用 proxy_read_timeout 指令增加此超时时间。
猜你喜欢
  • 2021-09-28
  • 1970-01-01
  • 2015-12-18
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 2015-01-15
  • 2021-03-29
  • 2021-06-19
相关资源
最近更新 更多