最初我在Socket.io中使用了MemoryStore,当我使用“heroku ps:scale web = 2”扩展它时,它开始间歇性地工作,并在客户端中给出了这个错误:
Uncaught TypeError: Property ‘open’ of object #<Transport> is not a function
我在Socket.io documentation中发现“如果你想扩展到多个进程和/或多个服务器,你可以使用我们的RedisStore,它使用Redis NoSQL数据库作为中间人”
所以,我创建了一个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个进程的日志:
您是否尝试过使用Node中的Cluster模块?2012-06-16T15:36:12+00:00 app[web.2]: debug: setting poll timeout
2012-06-16T15:36:12+00:00 app[web.2]: debug: clearing poll timeout
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]: warn: client not
handshaken client should reconnect 2012-06-16T15:36:12+00:00
app[web.2]: debug: set close timeout for client 15718037491002932534
2012-06-16T15:36:12+00:00 app[web.2]: debug: cleared close timeout for
client 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
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.