4

Redis で Node.js と Socket.io を使用して Heroku にアプリをデプロイしようとしています。Heroku で指定されている XHR ロング ポーリングを使用するように Socket.io をセットアップしました。dynoが 1 つしかない場合は完全に機能しますが、複数の dyno を使用するようにスケーリングすると機能しません。

最初はSocket.ioでMemoryStoreを使用していましたが、「heroku ps:scale web=2」を使用してスケールアップすると、断続的に動作し始め、クライアントで次のエラーが発生しました:

キャッチされていない TypeError: オブジェクト #<Transport> のプロパティ 'open' は関数ではありません

Socket.io のドキュメントで、「複数のプロセスや複数のサーバーにスケーリングしたい場合は、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 の 1 つの Web dyno で機能します。しかし、それを複数のプロセスにスケーリングするとすぐに、断続的に再び機能しなくなりますが、今ではエラーは発生しなくなりました。だから、ここからどこへ行けばいいのかわからない。

これらは、2 つのプロセスで Heroku から取得したログです。

2012-06-16T15:36:12+00:00 app[web.2]: デバッグ: ポーリング タイムアウトの設定
2012-06-16T15:36:12+00:00 app[web.2]: デバッグ: ポーリング タイムアウトのクリア
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]: デバッグ: クライアントのクローズ タイムアウトを設定します 15718037491002932534
2012-06-16T15:36:12+00 :00 アプリ [web.2]: デバッグ:
クライアント 15718037491002932534 のクローズ タイムアウトをクリアしました 2012-06-16T15:36:12+00:00 アプリ [web.2]:
情報: トランスポート終了 (エラー) 2012-06-16T15: 36:12+00:00 app[web.2]:
デバッグ: トランスポートを破棄しています

4

2 に答える 2

1

ノードのクラスターモジュールを使用してみましたか? 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);
    })
  });
}

あなたがここで見ることができるように。

于 2012-06-16T16:05:26.433 に答える
0

heroku でのスケーリングは heroku ps:scale {number} を使用して行われます。そこでプロセスを生成することはできません。私は今同じ問題を抱えています。

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

于 2012-07-03T16:22:32.263 に答える