为什么WebPack通过WebSockets不断地与前端服务器通信?

qltillow  于 2023-10-19  发布在  Webpack
关注(0)|答案(2)|浏览(164)

我最近使用以下软件组织配置了一台服务器(在开发过程中,dev.comlocalhost的别名):

------   if (dev.com)  ----> localhost:3000
                                      |
dev.com:443 / api.dev.com:443 --- [compute / nginx reverse proxy]
                                      |
                                      ------ if(api.dev.com) ----> localhost:8000

我的React应用程序似乎工作正常,除了开发人员控制台中定期打印的这些消息:

我认为这可能与Webpack有关。我对webpack不够熟悉,不知道它在这里做什么。我发现,如果我设置env WDS_SOCKET_PORT=443,那么连接继续失败,但看起来是这样的:

dev.com:443的连接应该通过代理路由到与下载初始站点包的连接相同的服务器。所以我不确定到底出了什么问题。
调用堆栈:

我的部门:

"dependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.4.0",
    "bootstrap": "^5.3.0",
    "jwt-decode": "^3.1.2",
    "nodemon": "^2.0.22",
    "react": "^18.2.0",
    "react-bootstrap": "^2.8.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.14.0",
    "react-scripts": "^5.0.1",
    "web-vitals": "^2.1.4"
  },

直到我代理了nginx背后的服务器才发生这种情况。你知道这是怎么回事吗?如果你知道 * 为什么 * webpack会保持与服务器的持续连接,那就更好了。
在env中导出DEBUG='express:*'后,我可以看到webpack开发服务器的调试日志。它似乎是从反向代理路由/ws请求-它似乎并不关心,并返回404。

express:router dispatching GET /ws +6s
  express:router query  : /ws +0ms
  express:router expressInit  : /ws +1ms
  express:router handleWebpackInternalMiddleware  : /ws +0ms
  express:router compression  : /ws +0ms
  express:router trim prefix (/ws) from url /ws +0ms
  express:router bound setHeaders /ws : /ws +0ms
  express:router middleware  : /ws +1ms
  express:router serveStatic  : /ws +0ms
  express:router <anonymous>  : /ws +9ms
  express:router middleware  : /ws +1ms
  express:router serveStatic  : /ws +0ms
  express:router middleware  : /ws +7ms
  express:router bound serveMagicHtml  : /ws +6ms
  express:router trim prefix (/ws) from url /ws +0ms
  express:router middleware /ws : /ws +0ms
  express:router redirectServedPathMiddleware  : /ws +1ms
  express:router noopServiceWorkerMiddleware  : /ws +0ms
5cg8jx4n

5cg8jx4n1#

看起来你正在使用一个包含react,webpack和webpack dev server的堆栈。
Webpack dev server将在启动时构建bundle,但如果源文件发生更改,它也可以在运行时(重新)构建。这就是为什么客户端需要一个WebSocket,以监控更改和实时更新网站(即。不刷新)...
将WDS_SOCKET_PORT更改为443是可以的。(或者0应转换为浏览器用于站点的内容)。
你有一个nginx反向代理服务器,但它与WebSocket失败。WebSocket确实使用http(s)进行设置,但随后会将连接升级到WebSocket。Nginx默认不传递Upgrade(和Connection)http头,所以升级失败。
最简单的解决方案是在nginx中添加一个额外的位置:

...
server {
  listen 443;
  server_name dev.com
  ...

  # added: note the equal sign and no slashes at the end
  location = /ws {
      proxy_pass http://localhost:3000/ws;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }

  # existing
  location / {
     proxy_pass http://localhost:3000/;
  }
}
...
lpwwtiir

lpwwtiir2#

Webpack的Dev Server使用WebSocket来给予Hot Module Replacement (HMR)支持。这样,它可以在您编写代码时将更新(或编译错误)推送到浏览器,这样您就可以立即看到更改,而无需刷新整个页面/选项卡。
您面临的问题似乎是,由于您使用的是代理,因此客户端代码无法连接到Webpack Dev Server的WebSocket服务器(在wss://localhost:3000/ws上侦听),因为代理阻止了这些请求。
您可以手动设置webSocketURL,以便您的客户端知道WebSocket服务器的正确URL(无论代理如何),如文档中所述:

webSocketURL

string object
此选项允许指定Web Socket服务器的URL(当您正在验证开发服务器和客户端脚本并不总是知道连接到哪里时很有用)。

webpack.config.js

module.exports = {
  //...
  devServer: {
    client: {
      webSocketURL: 'wss://localhost:3000/ws',
    },
  },
};

注意这个选项只会影响你的开发版本/流程,它不会对生产环境有任何影响。
或者,您可以更新代理,使其也将WebSocket请求转发给localhost:3000(就像HTTP请求一样),就像@user7994388的答案一样。

相关问题