我正在努力加快代理websockets的速度。我有一些角度代码,我从一个测试websocket连接的教程修改了echo.websocket.org。代码本身很好。
<!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>
按照https://github.com/nodejitsu/node-http-proxy#proxying-websockets
的说明操作我试图设置一个简单的代理2种不同的方式,通过改变角度代码中的wsUri变量指向其中一个,将角度页面的websocket请求转发到相同的echo.websocket.org连接。在此代码中创建的服务器。
///
// 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);
不幸的是,代理请求(对于端口8014和8015上的服务器侦听)触发了有问题的websocket.onerror事件处理程序,它为我提供了一个不太有用的消息“未定义”。对于evt.data。
更新:
当我尝试使用localhost代理打开网页时,Chrome会在开发人员工具中显示以下错误消息。index.htm:29 WebSocket连接到&#39; ws:// localhost:8015 /&#39;失败: WebSocket握手期间出错:意外的响应代码:404
Firefox在其中显示以下内容&#34; Web控制台&#34;
Firefox无法在ws:// localhost:8015 /。
建立与服务器的连接
但是,升级事件正在触发,因为我看到Node的控制台显示Node JS代码的console.log()行的套接字信息。这让我相信找到了localhost服务器,请求404错误的起源问题。我不确定它是否与查找代理(触发了其http升级事件)或代理的目标有关。
当浏览器和echo.websocket.org之间没有代理时,如何让Node JS代理角度websocket连接?
答案 0 :(得分:3)
<强> TLDR;
它与在转发代理请求之前设置Host: foo.com
标头有关。
基本上,Error during WebSocket handshake: Unexpected response code: 404
意味着它实际上无法与给定wsUri
建立任何连接。
从this issue看,changeOrigin
建议默认为true
。
但是,在我们的情况下它是false
(默认情况下)。因此,如果没有正确设置HTTP Host
标头,转发的请求将无效/格式错误。 您可以尝试进一步调试以查看真实的HTTP属性,标题等
另外,
autoRewrite
属性根据请求的主机/端口重写(201/301/302/307/308)重定向上的位置主机/端口。
尝试将以下属性添加为createServer()
个参数:
autoRewrite: true,
changeOrigin: true,
所以,它变成了:
const test = httpProxy.createServer({
target: 'ws://echo.websocket.org',
ws: true,
autoRewrite: true,
changeOrigin: true,
});
test.listen(8014);
希望它有所帮助!