102 votes

Comment utiliser redis PUBLISH / SUBSCRIBE avec nodejs pour avertir les clients lorsque les valeurs de données changent?

J'écris une application de publication / abonnement pilotée par événement avec NodeJS et Redis. J'ai besoin d'un exemple sur la façon de notifier les clients Web lorsque les valeurs de données dans Redis changent.

124voto

Alfred Points 32190

VIEUX utilisez uniquement une référence

Dépendances

utilise express, prise.io, node_redis et dernier mais pas moins l' exemple de code à partir du média d'incendie.

Installer node.js+mnp(non root)

D'abord, vous devez(si vous ne l'avez pas fait encore) installer node.js+mécanisme national de prévention de 30 secondes (le droit chemin parce que vous devez PAS exécuter des mnp en tant que root):

echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc
. ~/.bashrc
mkdir ~/local
mkdir ~/node-latest-install
cd ~/node-latest-install
curl http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install # ok, fine, this step probably takes more than 30 seconds...
curl http://npmjs.org/install.sh | sh

Installer les dépendances

Après l'installation d'un nœud+npm vous devez installer les dépendances par l'émission de:

npm install express
npm install socket.io
npm install hiredis redis # hiredis to use c binding for redis => FAST :)

Télécharger des exemples de

Vous pouvez télécharger l'échantillon de mediafire.

Décompressez le package

unzip pbsb.zip # can also do via graphical interface if you prefer.

Ce qui est à l'intérieur du zip

./app.js

const PORT = 3000;
const HOST = 'localhost';

var express = require('express');

var app = module.exports = express.createServer();

app.use(express.staticProvider(__dirname + '/public'));

const redis = require('redis');
const client = redis.createClient();

const io = require('socket.io');

if (!module.parent) {
    app.listen(PORT, HOST);
    console.log("Express server listening on port %d", app.address().port)

    const socket  = io.listen(app);

    socket.on('connection', function(client) {
        const subscribe = redis.createClient();
        subscribe.subscribe('pubsub'); //    listen to messages from channel pubsub

        subscribe.on("message", function(channel, message) {
            client.send(message);
        });

        client.on('message', function(msg) {
        });

        client.on('disconnect', function() {
            subscribe.quit();
        });
    });
}

./public/index.html

<html>
<head>
    <title>PubSub</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="/javascripts/jquery-1.4.3.min.js"></script>
</head>
<body>
    <div id="content"></div>
    <script>    
        $(document).ready(function() {
            var socket = new io.Socket('localhost', {port: 3000, rememberTransport: false/*, transports: ['xhr-polling']*/});
            var content = $('#content');

            socket.on('connect', function() {
            });

            socket.on('message', function(message){
                content.prepend(message + '<br />');
            }) ;

            socket.on('disconnect', function() {
                console.log('disconnected');
                content.html("<b>Disconnected!</b>");
            });

            socket.connect();
        });
    </script>
</body>
</html>

Démarrer le serveur

cd pbsb    
node app.js

Lancez le navigateur

Mieux si vous lancez google chrome(en raison des websockets support, mais pas nécessaire). Visite http://localhost:3000 pour voir l'échantillon(au début, vous ne voyez rien, mais PubSub que le titre).

Mais sur publish de canal pubsub vous devriez voir un message. Ci-dessous nous publions "Hello world!" pour le navigateur.

À partir de ./redis-cli

publish pubsub "Hello world!"

26voto

nak Points 962

voici un exemple simplifié, sans que de nombreuses dépendances. Vous n'avez encore besoin d' npm install hiredis redis

Le nœud JavaScript:

var redis = require("redis"),
    client = redis.createClient();

client.subscribe("pubsub");
client.on("message", function(channel, message){
  console.log(channel + ": " + message);
});

...un pubsub.js fichier et de l'exécuter node pubsub.js

dans redis-cli:

redis> publish pubsub "Hello Wonky!"
(integer) 1

qui doit s'afficher: pubsub: Hello Wonky! dans le terminal de nœud en cours d'exécution! Bravo!

Supplémentaires 4/23/2013: je tiens également à noter que lorsqu'un client s'abonne à un pub/sub canal, il va dans l'abonné mode et est limitée à l'abonné commandes. Vous aurez juste besoin de créer des instances supplémentaires de redis clients. client1 = redis.createClient(), client2 = redis.createClient() on peut donc être dans l'abonné mode et de l'autre, de publier régulièrement des DB commandes.

4voto

Awemo Points 407

Traitez les erreurs redis pour empêcher nodejs de quitter. Vous pouvez le faire en écrivant;

 subcribe.on("error", function(){
  //Deal with error
})
 

Je pense que vous obtenez une exception parce que vous utilisez le même client abonné pour publier des messages. Créez un client distinct pour la publication de messages et qui pourrait résoudre votre problème.

2voto

MattDiPasquale Points 23842

Consultez acani-node sur GitHub , en particulier le fichier acani-node-server.js . Si ces liens sont rompus, recherchez acani-chat-server parmi les référentiels publics de acit GitHub .

2voto

dirkk0 Points 451

Si vous voulez que cela fonctionne avec socket.io 0.7 ET un serveur Web externe, vous devez le modifier (en plus de staticProvider -> problème statique):

a) indiquez le nom de domaine à la place de localhost (c.-à-d. var socket = io.connect ('http://my.domain.com:3000');) dans le fichier index.html

b) changez HOST dans app.js (c'est-à-dire const HOST = 'my.domain.com';)

c) et ajoutez des sockets à la ligne 37 de app.js (c'est-à-dire 'socket.sockets.on (' connexion ', fonction (client)', fonction (client) {… ')

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X