我正在尝试使用Node.js和Redis的Socket.io将应用程序部署到Heroku。我已经设置了Socket.io来使用XHR长轮询作为specified by Heroku,如果我只有一个dyno它可以很好地工作,但是当我将它缩放以使用多个dynos时它不起作用。
最初我在Socket.io中使用了MemoryStore,当我使用“heroku ps:scale web = 2”进行扩展时,它开始间歇性地工作,并在客户端发出错误:
未捕获的TypeError:对象#< Transport>属性'open'不是一个功能
我在Socket.io documentation中找到“如果你想扩展到多个进程和/或多个服务器,你可以使用Redis NoSQL数据库作为中间人的RedisStore”
所以,我创建了一个RedisStore:
var newRedisStore = new RedisStore({
redisPub : pub,
redisSub : sub,
redisClient : client
});
并配置Socket.io使用它:
//set up Web Socket Server
io.configure(function () {
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
io.set('store', newRedisStore);
});
这一切都完美地在本地工作,并在Heroku中使用一个网络dyno。但是一旦我将它扩展到多个进程,它就会间歇性地开始不再工作,尽管现在我不再得到错误了。所以,我不确定从哪里开始。
这些是我从Heroku获得的2个进程的日志:
2012-06-16T15:36:12 + 00:00 app [web.2]:debug:设置轮询超时
2012-06-16T15:36:12 + 00:00 app [web.2]:debug:清除轮询超时
2012-06-16T15:36:12 + 00:00 app [web.2]:debug:xhr-polling writing
7 ::: 1 + 0 2012-06-16T15:36:12 + 00:00 app [web.2]:警告:客户不是
握手客户应该重新连接2012-06-16T15:36:12 + 00:00 app [web.2]:debug:设置客户端关闭超时15718037491002932534
2012-06-16T15:36:12 + 00:00 app [web.2]:debug:清除关闭超时为
客户15718037491002932534 2012-06-16T15:36:12 + 00:00 app [web.2]:
info:transport end(error)2012-06-16T15:36:12 + 00:00 app [web.2]:
debug:discarding transport
答案 0 :(得分:1)
您是否尝试过使用Node中的Cluster模块? http://nodejs.org/api/cluster.html
像:
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('death', function(worker) {
console.log('worker ' + worker.pid + ' died');
});
} else {
// Worker processes have a http server.
http.Server(function(req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
}
或者:
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
} else {
var sio = require('socket.io')
, RedisStore = sio.RedisStore
, io = sio.listen(8080, options);
// Somehow pass this information to the workers
io.set('store', new RedisStore);
// Do the work here
io.sockets.on('connection', function (socket) {
socket.on('chat', function (data) {
socket.broadcast.emit('chat', data);
})
});
}
就像你可以看到here。
答案 1 :(得分:0)
使用heroku ps:scale {number}完成heroku的缩放,你不能在那里生成进程。我现在也有同样的问题。