J'écris une application de publication / abonnement basée sur les événements avec NodeJS et Redis. J'ai besoin d'un exemple de la manière d'avertir les clients Web lorsque les valeurs de données dans Redis changent.
Réponses:
utilise express , socket.io , node_redis et enfin et surtout l' exemple de code de Media Fire.
Tout d'abord, vous devez (si vous ne l'avez pas encore fait) installer node.js + npm en 30 secondes (la bonne façon car vous ne devez PAS exécuter npm 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
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 :)
Vous pouvez télécharger un échantillon complet à partir de mediafire .
unzip pbsb.zip # can also do via graphical interface if you prefer.
./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>
cd pbsb
node app.js
Le mieux si vous démarrez Google Chrome (en raison de la prise en charge des websockets, mais pas nécessaire). Visitez http://localhost:3000
pour voir un échantillon (au début, vous ne voyez rien d'autre PubSub
que le titre).
Mais sur publish
le canal, pubsub
vous devriez voir un message. Ci-dessous, nous publions "Hello world!"
dans le navigateur.
publish pubsub "Hello world!"
voici un exemple simplifié sans autant de dépendances. Vous avez encore besoin denpm 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);
});
... 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 terminal en cours d'exécution node! Félicitations!
Supplémentaire 23/04/2013: Je tiens également à noter que lorsqu'un client s'abonne à un canal pub / sous, il passe en mode abonné et est limité aux commandes des abonnés. 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 DB régulières.
pubsub/*
simplement ajouter p
à l'exemple: remplacer subscibe
par psubscribe
et message
par pmessage
.
Nous essayions de comprendre Redis Publish / Subscribe (" Pub / Sub ") et tous les exemples existants étaient soit obsolètes, soit trop simples, soit sans tests. Nous avons donc écrit une discussion complète en temps réel à l'aide de l'exemple Hapi.js + Socket.io + Redis Pub / Sub avec des tests de bout en bout !
Le composant Pub / Sub n'est que quelques lignes de code node.js: https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40
Plutôt que de le coller ici ( sans aucun contexte ), nous vous encourageons à vérifier / essayer l' exemple .
Nous avons construit à l'aide Hapi.js mais le chat.js
fichier est découplé de Hapi et peut facilement être utilisé avec un base serveur http Node.js ou exprimer (etc.)
Gérez les erreurs redis pour empêcher nodejs de se fermer. Vous pouvez le faire en écrivant;
subcribe.on("error", function(){
//Deal with error
})
Je pense que vous obtenez l'exception parce que vous utilisez le même client qui est abonné pour publier des messages. Créez un client distinct pour publier des messages et cela pourrait résoudre votre problème.
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 GitHub d'acani .
Si vous voulez que cela fonctionne avec socket.io 0.7 ET un serveur Web externe, vous devez changer (en plus du staticProvider -> problème statique):
a) fournir le nom de domaine au lieu de localhost (c.-à-d. var socket = io.connect ('http://my.domain.com:3000');) dans l'index.html
b) changez HOST dans app.js (ie const HOST = 'my.domain.com';)
c) et ajoutez des sockets à la ligne 37 de app.js (ie 'socket.sockets.on (' connection ', function (client) {…')
selon la solution @alex . si vous avez une erreur comme celle-ci selon la mention @tyler :
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.
vous devez d'abord installer Redis . regarde ça:
const client = redis.createClient()
de la racine de app.js?