【问题标题】:Using Socket.io and Redis on Heroku with Node.js使用 Node.js 在 Heroku 上使用 Socket.io 和 Redis
【发布时间】:2012-06-19 08:37:00
【问题描述】:

我正在尝试使用 Node.js 和带有 Redis 的 Socket.io 将应用程序部署到 Heroku。我已经将 Socket.io 设置为使用 XHR 长轮询作为specified by Heroku,如果我只有一个测功机,它可以完美地工作,但是当我将它扩展到使用多个测功机时它就不起作用了。

最初我在 Socket.io 中使用 MemoryStore,当我使用“heroku ps:scale web=2”对其进行扩展时,它开始间歇性地工作,并在客户端出现此错误:

未捕获的类型错误:对象# 的属性“打开”不是函数

我在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 中使用一个 web dyno。但是,一旦我将它扩展到多个进程,它就会间歇性地开始不再工作,尽管现在我不再收到错误了。所以,我不确定从这里去哪里。

这些是我从 Heroku 获得的带有 2 个进程的日志:

2012-06-16T15:36:12+00:00 app[web.2]:调试:设置轮询超时
2012-06-16T15:36:12+00:00 应用 [web.2]:调试:清除轮询超时
2012-06-16T15:36:12+00:00 app[web.2]: 调试: xhr-polling 写作
7:::1+0 2012-06-16T15:36:12+00:00 应用程序[web.2]:警告:客户端不
握手客户端应重新连接 2012-06-16T15:36:12+00:00
app[web.2]:调试:为客户端 15718037491002932534 设置关闭超时
2012-06-16T15:36:12+00:00 app[web.2]: 调试: 清除关闭超时
客户端 15718037491002932534 2012-06-16T15:36:12+00:00 app[web.2]:
信息:传输端(错误)2012-06-16T15:36:12+00:00 app[web.2]:
调试:丢弃传输

【问题讨论】:

    标签: node.js heroku redis socket.io


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您是否尝试过使用 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

      【讨论】:

      • 谢谢。我觉得这是朝着正确的方向发展,但我似乎无法让它发挥作用。当我使用集群时,Socket.io 在发出时不断出错。
      • 尝试增加timeout 并告诉我。你也可以发布你的代码,所以我可以分析它,使用 pastebin.com 或类似的。
      猜你喜欢
      • 2014-11-25
      • 1970-01-01
      • 2012-05-02
      • 2015-05-04
      • 2017-06-30
      • 2016-07-28
      • 1970-01-01
      • 2014-01-31
      • 1970-01-01
      相关资源
      最近更新 更多