web-dev-qa-db-fra.com

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 de notification des clients Web lorsque les valeurs de données dans Redis changent.

95
guilin 桂林

OLD n'utilise qu'une référence

Les dépendances

utilise express , socket.io , node_redis et le dernier mais non le moindre, le exemple de code de Media Fire.

Installez node.js + npm (en tant qu'utilisateur non root)

D'abord, vous devriez (si vous ne l'avez pas encore fait) installer node.js + npm en 30 secondes (dans le bon sens car vous devriez [~ # ~] pas [~ # ~] lance npm en tant que racine ):

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 des dépendances

Après avoir installé node + npm, vous devez installer les dépendances en émettant:

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

Télécharger l'échantillon

Vous pouvez télécharger un échantillon complet à partir de mediafire .

Décompresser le paquet

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

Qu'y a-t-il à l'intérieur de 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

Lancer le navigateur

Idéal si vous démarrez Google Chrome (en raison de la prise en charge de websockets, mais non nécessaire). Visite http://localhost:3000 pour voir un exemple (au début, vous ne voyez rien d'autre que PubSub comme titre).

Mais sur publish pour canaliser pubsub, vous devriez voir un message. Nous publions ci-dessous "Hello world!" au navigateur.

De ./redis-cli

publish pubsub "Hello world!"
122
Alfred

voici un exemple simplifié sans autant de dépendances. Vous avez toujours besoin de npm install hiredis redis

Le noeud JavaScript:

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

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

... mettez cela dans un fichier pubsub.js et exécutez node pubsub.js

dans redis-cli:

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

qui devrait afficher: pubsub: Hello Wonky! dans le nœud d'exécution du terminal! Félicitations!

Supplémentaire 23/04/2013: Je veux également noter que lorsqu'un client s'abonne à un canal pub/sub, il passe en mode abonné et est limité aux commandes d'abonné. Vous aurez juste besoin de créer des instances supplémentaires de clients Redis. client1 = redis.createClient(), client2 = redis.createClient() donc l'un peut être en mode abonné et l'autre peut émettre des commandes de base de données régulières.

23
nak

Complet Redis Pub/Sous Exemple ( Chat en temps réel utilisant Hapi.js & Socket.io)

Nous essayions de comprendre Redis Publish/Subscribe (" Pub/Sub") et tous les exemples existants étaient soit obsolètes, trop simples ou n’avaient aucun test. Nous avons donc écrit un Complete Discussion en temps réel avec Hapi.js + Socket.io + Redis Pub/Sub Exemple avec tests de bout en bout !

https://github.com/dwyl/hapi-socketio- redis-chat-example

Le composant Pub/Sub ne contient que quelques lignes de code node.js: https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js# L33-L4

Plutôt que de le coller ici ( sans aucun contexte) nous encourageons vous souhaitez utiliser/essayer le exemple.

Nous l'avons construit en utilisant Hapi.js mais le chat.js Le fichier est découplé de Hapi et peut facilement être utilisé avec un basic noeud.js serveur http ou express (etc.)

7
nelsonic

Traitez les erreurs redis pour empêcher la sortie de nodejs. 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.

4
Awemo

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

a) fournissez le nom de domaine au lieu de localhost (c'est-à-dire var socket = io.connect ('http://my.domain.com:3000');) dans le fichier index.html

b) changer d'hôte dans app.js (c'est-à-dire const Host = 'my.domain.com';)

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

2
dirkk0

Découvrez 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 .

2
ma11hew28

Mise à jour du code:

staticProvider

maintenant renommé en

statique

voir guide de migration

1
Alex Mikhalev

selon @ alex solution. si vous avez une erreur comme celle-ci selon @ tyler mentionnez:

node.js:134
        throw e; // process.nextTick error, or 'error'

event on first tick ^ Error: Redis connection to 127.0.0.1:6379 failed - ECONNREFUSED, Connection refused at Socket.

alors vous devez installer Redis en premier. regarde ça:

http://redis.io/download

0
hbinduni