我正在使用Redis PubSub和NodeJS实现实时评论工具。在服务器上,我会监视req close或end事件,以确保我关闭/结束相应的订阅者。在我的OSX开发机器上,我能够检测到close事件,但在AWS elasticbeanstalk设置中,close事件不会被触发。我也尝试过听取其他事件(包括req和res),但那些似乎也不会发射!。
我的dev和aws设置都在aws上使用Node v0.12.2,Express v4.5.1 nginx 1.6.2。 aws设置在负载均衡器后面运行。
有没有其他人遇到类似这个问题的任何事情?
var publisherClient = redis.createClient();
publisherClient.on("error",function(err){
console.log(err);
})
setInterval(function(){
publisherClient.publish("Ping", '{"Pong":'+"}");
},20000)
exports.amastream=function (req,res){
req.socket.setTimeout(40*1000);
var messageCount = 0;
var subscriberClient = redis.createClient();
subscriberClient.subscribe("Ping");
subscriberClient.on("error", function(err) {
console.log("Redis Error: " + err);
});
subscriberClient.on("message", function(channel, message) {
messageCount++;
res.write('id: ' + messageCount + '\n');
res.write("data: " +channel + '\n');
res.write("data: " +message + '\n\n');
res.flush();
});
req.on("end", function() {
console.log("closing connection due to end of request!");
subscriberClient.punsubscribe();
subscriberClient.quit();
});
req.on("close", function() {
console.log("closing connection!");
subscriberClient.punsubscribe();
subscriberClient.quit();
});
req.on("error", function() {
console.log("closing connection due to abrupt ending!");
subscriberClient.punsubscribe();
subscriberClient.quit();
});
req.on("timeout",function() {
console.log("closing connection due to timeout!");
subscriberClient.punsubscribe();
subscriberClient.quit();
})
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Connection': 'keep-alive',
'Cache-Control': 'no-cache',
'You-Are-Like-Us':'Contact us at tarkeshwar@fundamine.com'
});
res.write('id: ' + 0 + '\n');
res.write("data: " +"first message" + '\n\n');
res.flush();
}
答案 0 :(得分:2)
我有同样的问题。此行为是由Elastic Load Balancing引起的。
我们应该看看Elastic Load Balancing Connection Timeout Management,以便更好地了解ELB如何运作。
因此,它具有客户端和后端连接以及空闲超时值。 由于某种原因, ELB无法正确检测客户端连接何时关闭并关闭相关的后端连接。实际上你的后端连接保持打开状态。这就是为什么你不接受近距离活动。
由于您向客户端发送ping,因此后端的空闲超时将不起作用。不管怎样,我想知道,如果客户端连接不存在,ELB在哪里发送这些数据?
AWS支持论坛上有关于此问题的post。主题启动器告诉关闭与后端的连接大约需要55分钟。从我的调查可能需要更长的时间。
我们还在我们的应用程序中使用Server-Sent Events,我们发现它导致了大量的空闲连接,这些连接在用户关闭或重新加载页面后由ELB保留。 您可以使用以下代码监控连接数(我没有在AWS上找到一个指标,它显示了从ELB到特定服务器的活动'后端和#e;连接的数量):
var server = require('http').createServer(app);
setInterval(function (){
server.getConnections(function (err, count){
console.log("Number of connections : " + count);
});
}, 60000);
不幸的是,我们无法迁移到Web套接字,因为如果没有其他解决方法或使用HAProxy服务器,EBS不支持它。
作为一种解决方法,可以设置一个定时器,它将每N分钟执行一次。在这种情况下,客户端代码应该检测到服务器连接已关闭并建立一个新连接。