Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to make WebSocket work with proxy settings? #8416

Closed
apiel opened this issue Feb 2, 2020 · 7 comments
Closed

How to make WebSocket work with proxy settings? #8416

apiel opened this issue Feb 2, 2020 · 7 comments

Comments

@apiel
Copy link

apiel commented Feb 2, 2020

I 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'
@codercodingthecode
Copy link

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

@chybisov
Copy link
Contributor

chybisov commented Feb 5, 2020

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

image
image

  app.use('/ws', proxy({
    target: 'SOME_API',
    changeOrigin: true,
    ws: true,
    secure: false,
    logLevel: 'debug'
  }));

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.

  app.use('/ws', proxy('/ws', {
    target: 'SOME_API',
    changeOrigin: true,
    ws: true,
    secure: false,
    logLevel: 'debug'
  }));

We need first '/ws' for

Mounts the specified middleware function or functions at the specified path: the middleware function is executed when the base of the requested path matches path.
From Express documentation.

And we need second '/ws' to specify context for http-proxy-middleware. If we skip this parameter then context is / and all websocket connections proxying to specified target option.

Now it works like a charm. Hope it helps someone. :)

@stale
Copy link

stale bot commented Mar 6, 2020

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

@stale stale bot added the stale label Mar 6, 2020
@apiel
Copy link
Author

apiel commented Mar 6, 2020

Still having the issue, did someone found a solution?

@stale stale bot removed the stale label Mar 6, 2020
@chybisov
Copy link
Contributor

chybisov commented Mar 6, 2020

@apiel did you check my answer above?

@stale
Copy link

stale bot commented Apr 5, 2020

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

@stale stale bot added the stale label Apr 5, 2020
@stale
Copy link

stale bot commented Apr 11, 2020

This issue has been automatically closed because it has not had any recent activity. If you have a question or comment, please open a new issue.

@stale stale bot closed this as completed Apr 11, 2020
@lock lock bot locked and limited conversation to collaborators Apr 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants