Mise À L'Échelle De La Prise.Les e / s multiples Node.js les processus à l'aide de cluster
Déchirer mes cheveux avec celui-ci... quelqu'un a réussi à l'échelle Socket.IO à de multiples "travailleur" processus engendré par Node.js's cluster module?
Permet de dire que j'ai le texte suivant sur quatre processus de travail (pseudo):
//on the server
var express = require('express');
var server = express();
var socket = require('socket.io');
var io = socket.listen(server);
//socket.io
io.set('store', new socket.RedisStore);
//set-up connections...
io.sockets.on('connection', function(socket) {
socket.on('join', function(rooms) {
rooms.forEach(function(room) {
socket.join(room);
});
});
socket.on('leave', function(rooms) {
rooms.forEach(function(room) {
socket.leave(room);
});
});
});
//Emit a message every second
function send() {
io.sockets.in('room').emit('data', 'howdy');
}
setInterval(send, 1000);
Et sur le navigateur...
//on the client
socket = io.connect();
socket.emit('join', ['room']);
socket.on('data', function(data){
console.log(data);
});
Le problème: Chaque seconde, je reçois quatre messages, en raison de quatre processus de travail de l'envoi des messages.
Comment puis-je m'assurer que le message n'est envoyé qu'une fois?
- La version de la prise.io utilisez-vous? Socket.IO 0.6 est conçu comme un processus unique serveur. Voir 3rdEden de réponse dans ce stackoverflow post. stackoverflow.com/questions/5944714/how-can-i-scale-socket-io
- 0.9.16 à l'aide de RedisStore
- Vous pouvez utiliser SocketCluster (interface de support est compatible avec la Prise.io): github.com/topcloud/socketcluster
Vous devez vous connecter pour publier un commentaire.
Edit: Dans Le Support.IO 1.0+, plutôt que de définir un magasin avec de multiples Redis clients, un simple Redis module adaptateur peut maintenant être utilisé.
L'exemple illustré ci-dessous devraient ressembler à ceci:
Si vous avez un nœud maître qui doit publier sur d'autres Support.IO processus, mais n'accepte pas les connexions socket lui-même, l'utilisation socket.io-émetteur au lieu de socket.io-redis.
Si vous rencontrez des problèmes de mise à l'échelle, l'exécution de votre Nœud applications avec
DEBUG=*
. Socket.IO implémente maintenant debug qui sera également imprimer Redis adaptateur messages de débogage. Exemple de sortie:Si les deux votre maître et votre enfant des processus à la fois d'afficher le même analyseur de messages, votre application est correctement mise à l'échelle.
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:
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:
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.Noter 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 exemple, l'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.socket.io.min.js:2 GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=LYqSrsK 404 (Not Found)
server.listen(80)
?Que le maître de la poignée de votre rythme cardiaque (exemple ci-dessous), ou de lancer plusieurs processus sur des ports différents à l'interne et à l'équilibre de la charge avec nginx (qui prend également en charge les websockets à partir de V1.3 vers le haut).
Cluster avec Maître
var socket = require('socket.io')(1338);
j'obtiens cette erreur: écouter EADDRINUSE :::1338 comment mettre en œuvre sur de même !Cela ressemble en fait à Douille.IO de la réussite à l'échelle. Vous attendez un message à partir d'un serveur pour aller à toutes les prises dans la salle, quel que soit le serveur auquel ils sont connectés.
Votre meilleur pari est d'avoir un processus maître qui envoie un message à chaque seconde. Vous pouvez le faire en seulement en cours d'exécution si
cluster.isMaster
, par exemple.De communication Inter-processus n'est pas assez pour faire la prise.io 1.4.5 de travail avec le cluster. Forcer websocket mode est également un must. Voir WebSocket poignée de main en Node.JS Douilles.IO et les Clusters ne fonctionne pas