用Node.js在Heroku上使用Socket.io和Redis

我试图用Redis的Node.js和Socket.io部署一个应用程序到Heroku。 我已经设置了Socket.io来使用Heroku指定的 XHR长轮询,如果我只有一个dyno,它就可以完美工作,但是当我使用多个dynos时,它不起作用。

最初,我在Socket.io中使用了一个MemoryStore,当我使用“heroku ps:scale web = 2”来扩展它时,它开始间歇性地工作,并在客户端给出这个错误:

Uncaught TypeError:对象#<Transport>的属性'open'不是一个函数

我在Socket.io文档中发现: “如果要扩展到多个进程和/或多个服务器,可以使用我们的RedisStore,它使用Redis NoSQL数据库作为中间人”

所以,我创build了一个RedisStore:

var newRedisStore = new RedisStore({ redisPub : pub, redisSub : sub, redisClient : client }); 

并configuration了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一个networkingdynamic。 但是,只要我把它扩展到多个进程,就会间歇性地开始不再工作,尽pipe现在我不会再犯这个错误了。 所以,我不确定该从哪里出发。

这些是我从Heroku获得的两个进程的日志:

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写作
7 ::: 1 + 0 2012-06-16T15:36:12 + 00:00 app [web.2]:warn:client not
握手客户端应重新连接2012-06-16T15:36:12 + 00:00
app [web.2]:debug:设置客户端15718037491002932534的closures超时
2012-06-16T15:36:12 + 00:00 app [web.2]:debug:清除closures超时
客户端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]:
debugging:丢弃传输

       

网上收集的解决方案 "用Node.js在Heroku上使用Socket.io和Redis"

你尝试使用节点的集群模块? 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); }) }); } 

就像你可以在这里看到的

heroku中的缩放是使用heroku ps:scale {number}完成的,你不能在那里产生进程。 我现在有同样的问题。

https://github.com/LearnBoost/socket.io/issues/939