How to make WebSocket work with proxy settings?
See original GitHub issueI try to proxy my websocket in dev mode using the manual proxy as described in the documentation https://create-react-app.dev/docs/proxying-api-requests-in-development/#configuring-the-proxy-manually
In my src/setupProxy.js
I have the following code:
const proxy = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
proxy('/isomor', {
target: 'http://127.0.0.1:3005',
ws: true,
}),
);
};
But when I try to connect, the connection get disconnected directly:
[HPM] GET /isomor -> http://127.0.0.1:3005
[HPM] Upgrading to WebSocket
[HPM] Client disconnected
When you look at the documentation of http-proxy-middleware they requiere server.on('upgrade', wsProxy.upgrade);
, see https://github.com/chimurai/http-proxy-middleware#external-websocket-upgrade
Or the http server
is not available in setupProxy.js
Did someone already manage to proxy websocket with create-react-app?
Edit
After debugguing the code for hours, I get the following error from http-proxy:
Error [ERR_STREAM_DESTROYED]: Cannot call write after a stream was destroyed
at doWrite (_stream_writable.js:431:19)
at writeOrBuffer (_stream_writable.js:419:5)
at Socket.Writable.write (_stream_writable.js:309:11)
at ClientRequest.<anonymous> (/home/alex/dev/node/pkg/isomor/packages/example/react/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js:157:14)
at ClientRequest.emit (events.js:223:5)
at Socket.socketOnData (_http_client.js:490:11)
at Socket.emit (events.js:223:5)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead (internal/stream_base_commons.js:181:23) {
code: 'ERR_STREAM_DESTROYED'
It seem that server.on('upgrade', wsProxy.upgrade);
is done by http-proxy-middleware
inside the middleware with req.connection.server
. But I wonder if this server
is the one expected by http-proxy
. When I try to instanciate my own websocket server I get some similar STREAM issue:
const proxy = require('http-proxy-middleware');
const WebSocket = require('ws');
let wss;
module.exports = function (app, server) {
app.use('/test', (req, res, next) => {
const { server } = req.connection;
if (!wss) {
wss = new WebSocket.Server({ server });
}
next();
});
};
With this code I get the following error:
events.js:200
throw er; // Unhandled 'error' event
^
Error [ERR_STREAM_WRITE_AFTER_END]: write after end
at writeAfterEnd (_stream_writable.js:257:14)
at Receiver.Writable.write (_stream_writable.js:306:5)
at Socket.socketOnData (/home/alex/dev/node/pkg/isomor/packages/example/react/node_modules/ws/lib/websocket.js:864:35)
at Socket.emit (events.js:228:7)
at addChunk (_stream_readable.js:309:12)
at readableAddChunk (_stream_readable.js:290:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead (internal/stream_base_commons.js:181:23)
Emitted 'error' event on WebSocket instance at:
at Receiver.receiverOnError (/home/alex/dev/node/pkg/isomor/packages/example/react/node_modules/ws/lib/websocket.js:769:13)
at Receiver.emit (events.js:223:5)
at errorOrDestroy (internal/streams/destroy.js:108:12)
at writeAfterEnd (_stream_writable.js:259:3)
at Receiver.Writable.write (_stream_writable.js:306:5)
[... lines matching original stack trace ...]
at TCP.onStreamRead (internal/stream_base_commons.js:181:23) {
code: 'ERR_STREAM_WRITE_AFTER_END'
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:7 (2 by maintainers)
That is the old version of cra, since 2.x it has it built-in. In my case, I get a similar proxy error with the latest cra when using this lib.![image](https://user-images.githubusercontent.com/20182536/73762953-66662e00-4736-11ea-8288-b26ee06f3b2f.png)
I have similar issue, this middleware works weird, it is somehow trying to proxy websocket sockjs-node request from webpackDevServer to my api server and I have these errors
So if I have two WS connections and one of them has proxy then webpack also proxy his sockjs-node to that server, but it shouldn’t do this.
UPDATE: I figured out how it actually works for me without proxying WebpackDevServer sockjs-node.
We need first
'/ws'
forAnd we need second
'/ws'
to specify context forhttp-proxy-middleware
. If we skip this parameter then context is/
and all websocket connections proxying to specifiedtarget
option.Now it works like a charm. Hope it helps someone. 😃