简体   繁体   English

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

[英]Using Socket.io and Redis on Heroku with Node.js

I'm trying to deploy an app to Heroku using Node.js and Socket.io with Redis. 我正在尝试使用Node.js和Redis的Socket.io将应用程序部署到Heroku。 I have set up Socket.io to use XHR long polling as specified by Heroku , and it works perfectly if I only have one dyno, but it doesn't work when I scale it to use multiple dynos. 我已经设置了Socket.io来使用Heroku指定的 XHR长轮询,如果我只有一个dyno它可以很好地工作,但是当我缩放它以使用多个dynos时它不起作用。

Initially I was using an MemoryStore in Socket.io, and when I scaled it up using "heroku ps:scale web=2", it started working intermittently, and giving this error in the client: 最初我在Socket.io中使用了MemoryStore,当我使用“heroku ps:scale web = 2”扩展它时,它开始间歇性地工作,并在客户端中给出了这个错误:

Uncaught TypeError: Property 'open' of object #<Transport> is not a function 未捕获的TypeError:对象#<Transport>的属性“open”不是函数

I found in the Socket.io documentation that "if you want to scale to multiple process and / or multiple servers you can use our RedisStore which uses the Redis NoSQL database as man in the middle" 我在Socket.io文档中发现“如果你想扩展到多个进程和/或多个服务器,你可以使用我们的RedisStore,它使用Redis NoSQL数据库作为中间人”

So, I created a RedisStore: 所以,我创建了一个RedisStore:

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

and configured Socket.io to use it: 并配置Socket.io来使用它:

//set up Web Socket Server
io.configure(function () { 
  io.set("transports", ["xhr-polling"]);
  io.set("polling duration", 10);
  io.set('store', newRedisStore);
});

And it all works perfectly locally and with one web dyno in Heroku. 它在本地完美运行,并在Heroku中使用一个网络dyno。 But as soon as I scale it to more than one process, it starts intermittently not working again, although now I don't get the error anymore. 但是一旦我将它扩展到多个进程,它就会间歇性地开始不再工作,尽管现在我不再得到错误了。 So, I'm not sure where to go from here. 所以,我不知道从哪里开始。

These are the logs I'm getting from Heroku with 2 processes: 这些是我从Heroku获得的2个进程的日志:

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:设置轮询超时
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:清除轮询超时
2012-06-16T15:36:12+00:00 app[web.2]: debug: xhr-polling writing 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 7 ::: 1 + 0 2012-06-16T15:36:12 + 00:00 app [web.2]:警告:客户不是
handshaken client should reconnect 2012-06-16T15:36:12+00:00 握手客户应该重新连接2012-06-16T15:36:12 + 00:00
app[web.2]: debug: set close timeout for client 15718037491002932534 app [web.2]:debug:为客户端设置关闭超时15718037491002932534
2012-06-16T15:36:12+00:00 app[web.2]: debug: cleared close timeout for 2012-06-16T15:36:12 + 00:00 app [web.2]:debug:清除关闭超时
client 15718037491002932534 2012-06-16T15:36:12+00:00 app[web.2]: 客户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]: info:transport end(error)2012-06-16T15:36:12 + 00:00 app [web.2]:
debug: discarding transport debug:丢弃传输

Did you try using Cluster module from Node? 您是否尝试过使用Node中的Cluster模块? http://nodejs.org/api/cluster.html http://nodejs.org/api/cluster.html

Like: 喜欢:

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);
}

Or: 要么:

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);
    })
  });
}

Like you can see here . 就像你在这里看到的一样。

Scaling at heroku is done using heroku ps:scale {number}, you can't spawn processes there. 使用heroku ps:scale {number}来完成heroku的缩放,你不能在那里生成进程。 I have the same issue right now. 我现在有同样的问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM