I am trying to get up to speed on proxying websockets. I have some angular code that I modified from a tutorial which tests websocket connections against echo.websocket.org. The code works fine by itself.
<!DOCTYPE html>
<html>
<meta charset = "utf-8" />
<title>WebSocket Test</title>
<script language = "javascript" type = "text/javascript">
var wsUri = "ws://echo.websocket.org/";
//var wsUri = "ws://localhost:8015"
var output;
var success = 0;
var failure = 0;
function init() {
output = document.getElementById("output");
output.innerHTML = "";
testWebSocket();
writeScore();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
};
websocket.onmessage = function(evt) {
onMessage(evt)
};
websocket.onerror = function(evt) {
onError(evt)
};
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
success = success +1;
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
function onMessage(evt) {
writeToScreen('<span style = "color: blue;">RESPONSE: ' +
evt.data+'</span>'); websocket.close();
}
function onError(evt) {
writeToScreen('<span style = "color: red;">ERROR:</span> '
+ evt.data);
failure = failure +1;
}
function doSend(message) {
writeToScreen("SENT: " + message); websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p");
pre.style.wordWrap = "break-word";
pre.innerHTML = message;
output.appendChild(pre);
}
function writeScore(){
var pScore = document.createElement("p");
pScore.style.wordWrap = "break-word";
pScore.innerHTML = "Success "+ success+ " Failures "+ failure;
output.appendChild(pScore);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id = "output"></div>
</html>
following the instructions from https://github.com/nodejitsu/node-http-proxy#proxying-websockets
I have tried to set up a simple proxy 2 different ways that will forward the angular page's websocket requests to the same echo.websocket.org connection by altering the wsUri variable in the angular code to point at one of the servers created in this code.
///
// Setup our server to proxy standard HTTP requests
//
var httpProxy = require('http-proxy');
var http = require('http');
var proxy = new httpProxy.createProxyServer({
target: {
host: 'echo.websocket.org',
port: 80
}
});
var proxyServer = http.createServer(function (req, res) {
proxy.web(req, res);
});
//
// Listen to the `upgrade` event and proxy the
// WebSocket requests as well.
//
proxyServer.on('upgrade', function (req, socket, head) {
console.log(socket);
proxy.ws(req, socket, head);
});
proxyServer.listen(8015);
var test = httpProxy.createServer({
target: 'ws://echo.websocket.org',
ws: true
});
test.listen(8014);
Unfortunately the proxied request (for both the sever listening on port 8014 and 8015) triggers the angular websocket.onerror event handler providing me a less than helpful message of 'undefined' for evt.data.
Update:
Chrome displays the following error message in developer tools when I try to open the webpage using the localhost proxies.
index.htm:29 WebSocket connection to 'ws://localhost:8015/' failed: Error during WebSocket handshake: Unexpected response code: 404
Firefox displays the following in it's "Web Console"
Firefox can’t establish a connection to the server at ws://localhost:8015/.
However, the upgrade event is firing as I am seeing the Node's console display the socket information from the console.log() line of the Node JS code. That leads me to believe that the localhost server is being found, begging the question for the origin of the 404 error. I'm not sure if it is related to the finding the proxy (which is having its http upgrade event triggered), or the proxy's target.
How do I get Node JS to proxy the angular websocket connection that works fine when no proxy is between the browser and echo.websocket.org?
autoRewrite: trueandchangeOrigin: trueinto yourcreateServer()arguments.