Open shellscape opened 7 years ago
What kind of client are you using to setup the connection? Did you try different ones to see if you see any difference?
@chimurai not sure I understand the question. I'm using the ws
WebSocket
client here, which is standards compliant with browser implementations. The code above was taken directly from the websocket example here and modified to match the failing case.
If you're referencing the const client...
line and related code; I ran a test via the browser with that const client =
and related code commented out, leaving the internalWss
active, and this was the result:
As soon as I commented out the internalWss
line, everything worked as per usual. So here again, it appears to be a conflict between http-proxy-middleware and multiple websocket servers running on localhost on different ports, with proxying enabled.
Thanks for the detailed report @shellscape. I'll have to spend some time investigating this.
Created a mini version of http-proxy-middleware to isolate the issue:
const httpProxyMiddleware = function (opts) {
const proxyServer = httpProxy.createProxyServer(opts)
const middleware = function (req, res, next) {
proxyServer.web(req, res, opts)
}
middleware.upgrade = function (req, socket, head) {
proxyServer.ws(req, socket, head)
}
return middleware
}
const wsProxy = proxy({
target: 'http://localhost:9090',
ws: true,
logLevel: 'debug'
});
RSV1 must be clear
error still present with this setup.
const express = require('express')
const WebSocket = require('ws');
const httpProxyMiddleware = function (opts) {
const proxyServer = httpProxy.createProxyServer(opts)
const middleware = function (req, res, next) {
proxyServer.web(req, res, opts)
}
middleware.upgrade = function (req, socket, head) {
proxyServer.ws(req, socket, head)
}
return middleware
}
const wsProxy = proxy({
target: 'http://localhost:9090',
ws: true,
logLevel: 'debug'
});
const wss = new WebSocket.Server({ port: 9090 });
wss.on('connection', (socket) => {
console.log('socket server connected');
socket.on('message', (message) => {
console.log('socket server message:', message);
socket.send(`response: ${message}`);
});
});
const app = express();
app.use('/', express.static(__dirname));
app.use(wsProxy);
const server = app.listen(8080, () => {
const internalWss = new WebSocket.Server({ server });
const client = new WebSocket('ws://localhost:8080');
client.on('message', (message) => {
console.log('client message:', message);
});
client.on('open', () => {
console.log('client open');
client.send('challenge');
});
});
server.on('upgrade', wsProxy.upgrade);
Error doesn't show when wrapping a setTimeout around const internalWss = new WebSocket.Server({ server });
setTimeout(() => {
const internalWss = new WebSocket.Server({ server })
}, 100)
@chimurai interesting. I wonder though if that setTimeout
setup only succeeded without error because the internalWss
wasn't yet created and listening when the client
message was sent.
@chimurai I have the same issue here: https://github.com/deep-foundation/deepcase-app/issues/223
Any ideas how to fix it now? We use the latest 2.0.6 version.
Expected behavior
Proxying to the locally running WebSocketServer on a different port succeeds.
Actual behavior
Proxying to the locally running WebSocketServer on a different port fails with an error of;
Error: RSV1 must be clear
. This is internally thrown byws
because the buffer that the server is receiving begins with bytes that are technically invalid. See below for triage.Setup
proxy middleware configuration
server mounting
This code block reproduces the issue with 100% of test runs locally here. If you comment out the line;
then the example runs successfully without error. There's some kind of caveat/edge case with there being a
WebSocketServer
connected to theserver
on port 8080, as well as bound tolocalhost:9090
. I did attempt to work my way through the http-proxy-middleware source to debug the cause but I came up empty. I also spent a fair amount of time within the source forws
to make sure that it wasn't an error there; in which I couldn't pinpoint a cause either. Given that the addition/removal of theWebSocketServer
on port 8080 (same as the server) caused failure/pass, I figured I'd start with an issue here.