Skip to content

Commit a530c9e

Browse files
committed
fix(ws): fix concurrent ws requests
1 parent 021b03f commit a530c9e

File tree

4 files changed

+59
-64
lines changed

4 files changed

+59
-64
lines changed

dist/http-proxy-middleware.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const Router = require("./router");
1919
class HttpProxyMiddleware {
2020
constructor(context, opts) {
2121
this.logger = logger_1.getInstance();
22-
this.wsInitialized = false;
2322
// https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
2423
this.middleware = (req, res, next) => __awaiter(this, void 0, void 0, function* () {
2524
if (this.shouldProxy(this.config.context, req)) {
@@ -35,16 +34,9 @@ class HttpProxyMiddleware {
3534
}
3635
});
3736
this.catchUpgradeRequest = server => {
38-
// subscribe once; don't subscribe on every request...
39-
// https://github.com/chimurai/http-proxy-middleware/issues/113
40-
if (!this.wsInitialized) {
41-
server.on('upgrade', this.wsUpgradeDebounced);
42-
this.wsInitialized = true;
43-
}
37+
server.once('upgrade', this.handleUpgrade);
4438
};
4539
this.handleUpgrade = (req, socket, head) => {
46-
// set to initialized when used externally
47-
this.wsInitialized = true;
4840
if (this.shouldProxy(this.config.context, req)) {
4941
const activeProxyOptions = this.prepareProxyRequest(req);
5042
this.proxy.ws(req, socket, head, activeProxyOptions);
@@ -120,8 +112,6 @@ class HttpProxyMiddleware {
120112
const errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors'; // link to Node Common Systems Errors page
121113
this.logger.error(errorMessage, req.url, hostname, target, err.code || err, errReference);
122114
};
123-
// https://github.com/chimurai/http-proxy-middleware/issues/57
124-
this.wsUpgradeDebounced = _.debounce(this.handleUpgrade);
125115
this.config = config_factory_1.createConfig(context, opts);
126116
this.proxyOptions = this.config.options;
127117
// create proxy
@@ -134,8 +124,7 @@ class HttpProxyMiddleware {
134124
this.proxy.on('error', this.logError);
135125
// https://github.com/chimurai/http-proxy-middleware/issues/19
136126
// expose function to upgrade externally
137-
// middleware.upgrade = wsUpgradeDebounced
138-
this.middleware.upgrade = this.wsUpgradeDebounced;
127+
this.middleware.upgrade = this.handleUpgrade;
139128
}
140129
}
141130
exports.HttpProxyMiddleware = HttpProxyMiddleware;

examples/websocket/index.html

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ <h2>WebSocket demo</h2>
3030
<p>
3131
<label for="location">location:</label>
3232
<input id="location" type="text" value="ws://localhost:3000">
33-
<button id="connect">connect</button>
34-
<button id="disconnect" disabled="disabled">disconnect</button>
33+
<button id="connectBtn">connect</button>
34+
<button id="disconnectBtn" disabled="disabled">disconnect</button>
3535
</p>
3636
</fieldset>
3737
<fieldset id="messaging" disabled="disabled">
3838
<p>
3939
<label for="message">message:</label>
4040
<input type="text" id="message" value="Hello WebSocket">
41-
<button id="send">send</button>
41+
<button id="sendBtn">send</button>
4242
</p>
4343
<p>
4444
<label for="logger">log:</label>
@@ -49,44 +49,61 @@ <h2>WebSocket demo</h2>
4949
<script>
5050
window.onload = function () {
5151
// elements
52-
var configuration = document.getElementById('configuration');
53-
var location = document.getElementById('location');
54-
var connect = document.getElementById('connect');
55-
var disconnect = document.getElementById('disconnect');
56-
var messaging = document.getElementById('messaging');
57-
var message = document.getElementById('message');
58-
var send = document.getElementById('send');
59-
var logger = document.getElementById('logger');
52+
const configuration = document.getElementById('configuration');
53+
const location = document.getElementById('location');
54+
const connectBtn = document.getElementById('connectBtn');
55+
const disconnectBtn = document.getElementById('disconnectBtn');
56+
const messaging = document.getElementById('messaging');
57+
const message = document.getElementById('message');
58+
const sendBtn = document.getElementById('sendBtn');
59+
const logger = document.getElementById('logger');
6060

6161
// ws
62-
var socket;
63-
64-
connect.onclick = function () {
65-
connect.disabled = true;
66-
disconnect.disabled = false;
67-
messaging.disabled = false;
68-
69-
socket = new WebSocket(location.value);
70-
socket.onopen = function () { log('CONNECTED'); };
71-
socket.onclose = function () { log('DISCONNECTED'); };
72-
socket.onerror = function () { log('SOCKET ERROR OCCURED'); };
73-
socket.onmessage = function (msg) { log('RECEIVED:' + msg.data); };
62+
let socket;
63+
64+
connectBtn.onclick = () => { connect(); }
65+
disconnectBtn.onclick = () => { disconnect(); }
66+
sendBtn.onclick = () => { sendMessage(message.value); }
67+
68+
function connect() {
69+
setupSocket(location.value);
7470
}
7571

76-
disconnect.onclick = function () {
77-
connect.disabled = false;
78-
disconnect.disabled = true;
79-
messaging.disabled = true;
80-
socket.close();
72+
function disconnect() {
73+
socket.close();
74+
socket = undefined;
8175
}
8276

83-
send.onclick = function () {
84-
log('SEND: ' + message.value);
85-
socket.send(message.value);
77+
function sendMessage(val) {
78+
log('SEND: ' + val);
79+
socket.send(val);
8680
};
8781

82+
function setupSocket(url) {
83+
socket = new WebSocket(url);
84+
socket.addEventListener('open', () => {
85+
log('CONNECTED');
86+
toggleControls();
87+
})
88+
socket.addEventListener('close', () => {
89+
log('DISCONNECTED');
90+
toggleControls()
91+
})
92+
socket.addEventListener('error', () => { log('SOCKET ERROR OCCURED'); })
93+
socket.addEventListener('message', (msg) => { log('RECEIVED:' + msg.data); })
94+
}
95+
8896
function log (message) {
89-
logger.value = logger.value + message + '\n'
97+
logger.value = logger.value + message + '\n';
98+
logger.scrollTop = logger.scrollHeight; // scroll to bottom
99+
}
100+
101+
function toggleControls() {
102+
[connectBtn, disconnectBtn, messaging].forEach(el => toggleEnabled(el))
103+
}
104+
105+
function toggleEnabled(el) {
106+
el.disabled = (el.disabled) ? false : true;
90107
}
91108

92109
}

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "http-proxy-middleware",
3-
"version": "0.19.1",
3+
"version": "0.20.0-beta.1",
44
"description": "The one-liner node.js proxy middleware for connect, express and browser-sync",
55
"main": "dist/index.js",
66
"files": [
@@ -15,11 +15,12 @@
1515
"build": "tsc",
1616
"pretest": "yarn build",
1717
"test": "jest --runInBand",
18-
"precover": "yarn clean && npm run build",
18+
"precover": "yarn clean && yarn build",
1919
"cover": "jest --runInBand --coverage",
20-
"precoveralls": "yarn clean && npm run build",
20+
"precoveralls": "yarn clean && yarn build",
2121
"coveralls": "jest --runInBand --coverage --coverageReporters=text-lcov | coveralls",
22-
"postcoveralls": "yarn clean"
22+
"postcoveralls": "yarn clean",
23+
"prepublish": "yarn build"
2324
},
2425
"repository": {
2526
"type": "git",

src/http-proxy-middleware.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,13 @@ import * as Router from './router';
99

1010
export class HttpProxyMiddleware {
1111
private logger = getInstance();
12-
private wsUpgradeDebounced;
1312
private config;
14-
private wsInitialized = false;
13+
// private wsInitialized = false;
1514
private proxyOptions;
1615
private proxy;
1716
private pathRewriter;
1817

1918
constructor(context, opts) {
20-
// https://github.com/chimurai/http-proxy-middleware/issues/57
21-
this.wsUpgradeDebounced = _.debounce(this.handleUpgrade);
2219
this.config = createConfig(context, opts);
2320
this.proxyOptions = this.config.options;
2421

@@ -42,8 +39,7 @@ export class HttpProxyMiddleware {
4239

4340
// https://github.com/chimurai/http-proxy-middleware/issues/19
4441
// expose function to upgrade externally
45-
// middleware.upgrade = wsUpgradeDebounced
46-
(this.middleware as any).upgrade = this.wsUpgradeDebounced;
42+
(this.middleware as any).upgrade = this.handleUpgrade;
4743
}
4844

4945
// https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript#red-flags-for-this
@@ -62,18 +58,10 @@ export class HttpProxyMiddleware {
6258
};
6359

6460
private catchUpgradeRequest = server => {
65-
// subscribe once; don't subscribe on every request...
66-
// https://github.com/chimurai/http-proxy-middleware/issues/113
67-
if (!this.wsInitialized) {
68-
server.on('upgrade', this.wsUpgradeDebounced);
69-
this.wsInitialized = true;
70-
}
61+
server.once('upgrade', this.handleUpgrade);
7162
};
7263

7364
private handleUpgrade = (req, socket, head) => {
74-
// set to initialized when used externally
75-
this.wsInitialized = true;
76-
7765
if (this.shouldProxy(this.config.context, req)) {
7866
const activeProxyOptions = this.prepareProxyRequest(req);
7967
this.proxy.ws(req, socket, head, activeProxyOptions);

0 commit comments

Comments
 (0)