使用 http-proxy-middleware 处理 WebSocket 错误

Posted

技术标签:

【中文标题】使用 http-proxy-middleware 处理 WebSocket 错误【英文标题】:Handle WebSocket error with http-proxy-middleware 【发布时间】:2019-11-22 13:57:07 【问题描述】:

我正在使用 http-proxy-middleware 将一些 API 端点代理到我的 Create React App 开发服务器。

我最近引入了一个 WebSocket 端点,我在 setupProxy.js 中使用以下代码对其进行代理:

const proxy = require('http-proxy-middleware');

const target = 'http://localhost:8000';

module.exports = function(app) 
  [...] // other proxies for HTTP endpoints
  app.use(proxy('/api/ws',  ws: true, target ));
;

我遇到的问题是,如果我重新启动后端,并且 WebSocket 连接中断,整个开发服务器会崩溃:

[HPM] Upgrading to WebSocket
events.js:170
      throw er; // Unhandled 'error' event
      ^

Error: read ECONNRESET
    at TCP.onStreamRead (internal/stream_base_commons.js:171:27)
Emitted 'error' event at:
    at emitErrorNT (internal/streams/destroy.js:91:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
    at processTicksAndRejections (internal/process/task_queues.js:81:17)
error Command failed with exit code 1.

我想知道如何优雅地处理 WebSocket 代理中的错误,以便服务器不会崩溃,而是等待 WebSocket 再次可用?

【问题讨论】:

您的意思是,您的 WebSocket 正在尝试在目标启动之前连接到目标? WebSocket 服务器起来了,express 服务器起来了,它找到了WebSocket,一切正常。然后,突然,WebSocket 服务器重新启动,我得到了错误。 你使用什么版本的节点?你能发布你的package-lock.json吗? 是节点11.15.0,不幸的是我无法发布锁定文件,但我很确定这不是版本问题,只是套接字断开连接的那一刻我应该处理不知何故出错。 好吧,我无法在节点 v13.0.0、express4.17.1、http-proxy1.18.0、http-proxy-middleware0.20.0 上重现此问题。代理在控制台中记录ECONNRESET 并继续运行。也许实际上您应该将其视为(其中一个)库中的错误。 【参考方案1】:

此问题不会在相关软件包的当前版本中重现,并且可能是由过时的、错误的依赖项引起的;如果没有询问者的锁定文件,调查它是哪个依赖项可能是不可行的。使用下面列出的软件包版本,代理服务器不会崩溃,而是会记录错误并继续运行。此行为在 src/http-proxy-middleware.ts 中启用,希望启用自定义错误处理的人可能会感兴趣。

未观察到崩溃的package-lock.json 总结:

accepts: 1.3.7
array-flatten: 1.1.1
async-limiter: 1.0.1
body-parser: 1.19.0
braces: 3.0.2
bytes: 3.1.0
content-disposition: 0.5.3
content-type: 1.0.4
cookie: 0.4.0
cookie-signature: 1.0.6
debug: 3.2.6
depd: 1.1.2
destroy: 1.0.4
ee-first: 1.1.1
encodeurl: 1.0.2
escape-html: 1.0.3
etag: 1.8.1
eventemitter3: 4.0.0
express: 4.17.1
fill-range: 7.0.1
finalhandler: 1.1.2
follow-redirects: 1.9.0
forwarded: 0.1.2
fresh: 0.5.2
http-errors: 1.7.2
http-proxy: 1.18.0
http-proxy-middleware: 0.20.0
iconv-lite: 0.4.24
inherits: 2.0.3
ipaddr.js: 1.9.0
is-extglob: 2.1.1
is-glob: 4.0.1
is-number: 7.0.0
lodash: 4.17.15
media-typer: 0.3.0
merge-descriptors: 1.0.1
methods: 1.1.2
micromatch: 4.0.2
mime: 1.6.0
mime-db: 1.42.0
mime-types: 2.1.25
ms: 2.1.2
negotiator: 0.6.2
on-finished: 2.3.0
parseurl: 1.3.3
path-to-regexp: 0.1.7
picomatch: 2.1.1
proxy-addr: 2.0.5
qs: 6.7.0
range-parser: 1.2.1
raw-body: 2.4.0
requires-port: 1.0.0
safe-buffer: 5.1.2
safer-buffer: 2.1.2
send: 0.17.1
serve-static: 1.14.1
setprototypeof: 1.1.1
statuses: 1.5.0
to-regex-range: 5.0.1
toidentifier: 1.0.0
type-is: 1.6.18
unpipe: 1.0.0
utils-merge: 1.0.1
vary: 1.1.2
ws: 7.2.0

【讨论】:

【参考方案2】:

我也遇到了同样的问题。只需将 http-proxy-middleware 升级到 0.20.0 就可以了

【讨论】:

以上是关于使用 http-proxy-middleware 处理 WebSocket 错误的主要内容,如果未能解决你的问题,请参考以下文章

React18使用 http-proxy-middleware代理跨域

React axios 使用 http-proxy-middleware 解决跨域问题小记

使用axios以及http-proxy-middleware代理处理跨域的问题

node.js中使用http-proxy-middleware请求转发给其它服务器

在使用 http-proxy-middleware 代理到 websocket 服务器之前,如何进行一些验证?

创建 React App http-proxy-middleware 不工作