Il ne devrait pas être un problème avec votre configuration si vous êtes émettant à partir d'un seul travailleur. Ce que vous faites est émise par les quatre travailleurs, et en raison de Redis publier/souscrire, les messages ne sont pas dupliquées, mais écrit à quatre reprises, comme vous l'avez demandé l'application à réaliser. Voici un schéma simplifié de ce qui ne Redis:
Client <-- Worker 1 emit --> Redis
Client <-- Worker 2 <----------|
Client <-- Worker 3 <----------|
Client <-- Worker 4 <----------|
Comme vous pouvez le voir, lorsque vous émettez à partir d'un travailleur, il publiera le émettent à Redis, et il sera mis en miroir des autres travailleurs, qui ont souscrit à le Redis. Cela signifie également que vous pouvez utiliser de multiples serveurs socket connecté de la même instance, et un émettent sur un serveur sera tiré sur tous les serveurs connectés.
Avec cluster, lorsqu'un client se connecte, il va se connecter à l'un de vos quatre travailleurs, pas tous les quatre. Cela signifie également que tout ce que vous émettez à partir de ce travailleur ne sera affiché une fois pour le client. Donc oui, l'application est mise à l'échelle, mais la façon dont vous le faites, vous êtes en émettant des quatre travailleurs, et le Redis, il est comme si vous étiez en appelant à quatre reprises sur un seul travailleur. Si un client connecté à tous les quatre de vos socket cas, ils seraient réception de seize messages par seconde, et non pas quatre.
Le type de socket de la manipulation dépend du type d'application que vous allez avoir. Si vous allez gérer les clients individuellement, alors vous devriez avoir aucun problème, parce que la connexion de l'événement se déclenche uniquement pour un travailleur par un client. Si vous avez besoin d'un mondial "battement de coeur", alors vous pourriez avoir un socket gestionnaire dans votre processus maître. Depuis le décès de travailleurs lorsque le processus maître meurt, vous devez compenser la connexion de charge sur le processus maître, et laissez les enfants à gérer les connexions. Voici un exemple:
var cluster = require('cluster');
var os = require('os');
if (cluster.isMaster) {
// we create a HTTP server, but we do not use listen
// that way, we have a socket.io server that doesn't accept connections
var server = require('http').createServer();
var io = require('socket.io').listen(server);
var fs = require('fs');
var RedisStore = require('socket.io/lib/stores/redis');
var redis = require('socket.io/node_modules/redis');
io.set('store', new RedisStore({
redisPub: redis.createClient(),
redisSub: redis.createClient(),
redisClient: redis.createClient()
}));
setInterval(function() {
// all workers will receive this in Redis, and emit
io.sockets.emit('data', 'payload');
}, 1000);
for (var i = 0; i < os.cpus().length; i++) {
cluster.fork();
}
cluster.on('exit', function(worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
}
if (cluster.isWorker) {
var express = require('express');
var app = express();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var RedisStore = require('socket.io/lib/stores/redis');
var redis = require('socket.io/node_modules/redis');
io.set('store', new RedisStore({
redisPub: redis.createClient(),
redisSub: redis.createClient(),
redisClient: redis.createClient()
}));
io.sockets.on('connection', function(socket) {
socket.emit('data', 'connected to worker: ' + cluster.worker.id);
});
app.listen(80);
}
Dans l'exemple, il y a cinq Socket.IO instances, l'une étant le maître, et quatre enfants. Le serveur maître n'appelle jamais listen()
donc il n'y a pas de connexion au-dessus sur ce processus. Toutefois, si vous appelez un émettent sur le processus maître, il sera publié à Redis, et les quatre processus de travail va effectuer le émettent sur leurs clients. Cela compense la connexion de la charge des travailleurs, et si un travailleur est de mourir, votre principale de l'application de la logique serait pas abordée dans le maître.
Notez qu'avec le Redis, tous les émet, même dans un espace de noms ou de la salle seront traitées par d'autres processus de travail, comme si vous déclenchée le émettent à partir de ce processus. En d'autres termes, si vous avez deux Prise.IO instances avec un Redis instance, appel emit()
sur un socket dans le premier travailleur va envoyer les données de ses clients, tandis que les travailleurs des deux fera la même chose que si vous l'avez appelé le émettent à partir de ce travailleur.