Javascript Node.js http代理删除websocket请求
好吧,我花了一个多星期的时间试图弄明白这一点,但没有结果,所以如果有人有线索,你就是英雄。这不是一个容易回答的问题,除非我是个笨蛋 我正在使用node http proxy将粘性会话代理给在不同端口上运行的16个node.js Worker 我使用Socket.IO的Web套接字来处理一系列不同类型的请求,也使用传统的请求 当我将服务器切换到通过节点http代理进行代理时,出现了一个新问题,有时我的Socket.IO会话无法建立连接 实际上,我无法在我的一生中稳定地复制它,打开它的唯一方法是将大量流量从多个客户端发送到服务器 如果我重新加载用户的浏览器,它有时可以重新连接,有时不能 棘手的会议 我必须代理粘性会话,因为我的应用程序基于每个工作人员进行身份验证,因此它基于其Connect.SID cookie(我使用的是Connect/express)路由请求 好的,一些代码 这是我的proxy.js文件,它在节点中运行,并路由到每个worker:Javascript Node.js http代理删除websocket请求,javascript,node.js,socket.io,node-http-proxy,Javascript,Node.js,Socket.io,Node Http Proxy,好吧,我花了一个多星期的时间试图弄明白这一点,但没有结果,所以如果有人有线索,你就是英雄。这不是一个容易回答的问题,除非我是个笨蛋 我正在使用node http proxy将粘性会话代理给在不同端口上运行的16个node.js Worker 我使用Socket.IO的Web套接字来处理一系列不同类型的请求,也使用传统的请求 当我将服务器切换到通过节点http代理进行代理时,出现了一个新问题,有时我的Socket.IO会话无法建立连接 实际上,我无法在我的一生中稳定地复制它,打开它的唯一方法是将大
var http = require('http');
var httpProxy = require('http-proxy');
// What ports the proxy is routing to.
var data = {
proxyPort: 8888,
currentPort: 8850,
portStart: 8850,
portEnd: 8865,
};
// Just gives the next port number.
nextPort = function() {
var next = data.currentPort++;
next = (next > data.portEnd) ? data.portStart : next;
data.currentPort = next;
return data.currentPort;
};
// A hash of Connect.SIDs for sticky sessions.
data.routes = {}
var svr = httpProxy.createServer(function (req, res, proxy) {
var port = false;
// parseCookies is just a little function
// that... parses cookies.
var cookies = parseCookies(req);
// If there is an SID passed from the browser.
if (cookies['connect.sid'] !== undefined) {
var ip = req.connection.remoteAddress;
if (data.routes[cookies['connect.sid']] !== undefined) {
// If there is already a route assigned to this SID,
// make that route's port the assigned port.
port = data.routes[cookies['connect.sid']].port;
} else {
// If there isn't a route for this SID,
// create the route object and log its
// assigned port.
port = data.currentPort;
data.routes[cookies['connect.sid']] = {
port: port,
}
nextPort();
}
} else {
// Otherwise assign a random port, it will/
// pick up a connect SID on the next go.
// This doesn't really happen.
port = nextPort();
}
// Now that we have the chosen port,
// proxy the request.
proxy.proxyRequest(req, res, {
host: '127.0.0.1',
port: port
});
}).listen(data.proxyPort);
// Now we handle WebSocket requests.
// Basically, I feed off of the above route
// logic and try to route my WebSocket to the
// same server regular requests are going to.
svr.on('upgrade', function (req, socket, head) {
var cookies = parseCookies(req);
var port = false;
// Make sure there is a Connect.SID,
if (cookies['connect.sid'] != undefined) {
// Make sure there is a route...
if (data.routes[cookies['connect.sid']] !== undefined) {
// Assign the appropriate port.
port = data.routes[cookies['connect.sid']].port;
} else {
// this has never, ever happened, i've been logging it.
}
} else {
// this has never, ever happened, i've been logging it.
};
if (port === false) {
// this has never happened...
};
// So now route the WebSocket to the same port
// as the regular requests are getting.
svr.proxy.proxyWebSocketRequest(req, socket, head, {
host: 'localhost',
port: port
});
});
客户端/现象
插座连接方式如下:
var socket = io.connect('http://whatever:8888');
在登录大约10秒钟后,我在这个侦听器上得到了这个错误,这没有多大帮助
socket.on('error', function (data) {
// this is what gets triggered. ->
// Firefox can't establish a connection to the server at ws://whatever:8888/socket.io/1/websocket/Nnx08nYaZkLY2N479KX0.
});
浏览器发送的Socket.IO GET请求永远不会返回-它只是挂起挂起,即使在错误返回后也是如此,因此看起来像是超时错误。服务器从未响应
服务器端-工作程序
这是工作者接收套接字请求的方式。很简单。所有员工都有相同的代码,所以您认为其中一人会收到请求并确认它
app.sio.socketio.sockets.on('connection', function (socket) {
// works... some of the time! all of my workers run this
// exact same process.
});
总结
这是大量的数据,我怀疑是否有人愿意面对它,但我完全被难住了,不知道下一步去哪里检查,下一步去记录,不管怎样,去解决它。我尽我所能想知道问题出在哪里,但毫无结果
更新
好的,我很确定问题出在以下的声明中:
节点http代理是我同意六氰化物。对我来说,通过redis之类的服务或某种消息查询系统让工作人员排队最有意义。工人将通过Redis发布/订阅功能由web节点(代理)排队。工作人员将通过“数据”事件实时回调错误、完成或流式处理数据。也许去图书馆看看。您还可以推出自己的类似库。RabbitMQ是用于类似目的的另一个系统 如果您已经在使用socket.io技术,我会使用socket.io,但您需要为其预期目的使用工具。Redis或MQ系统将是最有意义的,并与WebSocket(socket.io)完美结合,以创建实时、深入的应用程序
aws的弹性负载平衡器支持会话关联(粘性会话),这支持WebSocket。PaaS提供程序()正是这样做的。还有一个为node http proxy提供粘性会话的应用程序,但是我不知道它是否支持WebSocket。一般来说,我不认为node作为代理服务器不是最常用的选项,我认为node作为node的前端服务器使用,它是一个非常好的组合。下面是一些安装和使用nginx sticky sessions模块的方法 它是一个轻量级的前端服务器,具有类似json的配置,坚固且经过良好测试 如果您想提供静态页面、css,nginx的速度也要快得多。它非常适合配置缓存头、根据域将流量重定向到多个服务器、粘性会话、压缩css和javascript等
<>你也可以考虑一个纯负载均衡的开源解决方案。无论如何,我不认为node是实现这一点的最佳工具,最好只使用它来实现后端,并在它前面放一些类似nginx的东西来处理通常的前端服务器任务。我自己也在研究类似的东西,目的是生成(和销毁)Node.js动态集群节点 免责声明:我仍然不建议对Node执行此操作;nginx对于您正在寻找的设计体系结构更为稳定,甚至对于HAProxy更为稳定(非常成熟,并且很容易支持粘性会话代理)。正如@tsturzl所指出的,有
卫星,但鉴于下载量很低,我会小心行事(至少在生产环境中)
这就是说,由于您似乎已经使用Node设置了所有内容,因此重建和重新设计可能比它的价值更大。因此,要安装带有NPM的分支:
使用npm卸载节点代理
和/或sudo npm-d卸载节点代理
下载branch.zip并解压缩它
运行npm-g安装/path/to/node http代理caronte
在我的例子中,安装链接已断开,因此我必须运行sudo npm link http proxy
我已经使用他们的基本代理示例安装并运行了它——无论这是否解决了您的丢弃会话问题,只有您自己知道。您使用的是哪个版本的节点?看起来它可能与此相关:-有一个带修复的pull请求,但显然这并不能解决所有问题。v0.10.13-这太旧了吗?老实说,我不太确定它到底在哪里。评论中提到他们在0.10.13中仍然存在问题。你能准确地解释一下你想用它实现什么吗?也许有更好的方法来做事情。很抱歉问一下,为什么你首先需要粘性训练?如果是身份验证,通常可以通过使用redis商店来解决。谢谢,这些都是好主意,我正在研究它们,看看它们是否能够解决问题。有一个问题-你说我需要使用专门用于