Piszę opartą na zdarzeniach aplikację publikowania / subskrybowania z NodeJS i Redis. Potrzebuję przykładu, jak powiadamiać klientów WWW o zmianie wartości danych w Redis.
Odpowiedzi:
używa express , socket.io , node_redis i wreszcie przykładowy kod z media fire.
Najpierw powinieneś (jeśli jeszcze tego nie zrobiłeś) zainstalować node.js + npm w 30 sekund (właściwy sposób, ponieważ NIE powinieneś uruchamiać npm jako 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
Po zainstalowaniu node + npm powinieneś zainstalować zależności, wydając:
npm install express
npm install socket.io
npm install hiredis redis # hiredis to use c binding for redis => FAST :)
Możesz pobrać pełną próbkę z 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
Najlepiej, jeśli uruchomisz Google Chrome (ze względu na obsługę gniazd sieciowych, ale nie jest to konieczne). Odwiedź, http://localhost:3000aby zobaczyć próbkę (na początku nie widzisz niczego, ale PubSubjako tytuł).
Ale na publishkanale pubsubpowinieneś zobaczyć wiadomość. Poniżej publikujemy "Hello world!"w przeglądarce.
publish pubsub "Hello world!"
oto uproszczony przykład bez tylu zależności. Nadal musisznpm install hiredis redis
Węzeł JavaScript:
var redis = require("redis"),
client = redis.createClient();
client.subscribe("pubsub");
client.on("message", function(channel, message){
console.log(channel + ": " + message);
});
... umieść to w pliku pubsub.js i uruchom node pubsub.js
w redis-cli:
redis> publish pubsub "Hello Wonky!"
(integer) 1
który powinien wyświetlić: pubsub: Hello Wonky!w węźle działającym terminala! Gratulacje!
Dodatkowe 23.04.2013: Chcę również zauważyć, że kiedy klient subskrybuje kanał pub / sub, przechodzi w tryb subskrybenta i jest ograniczony do poleceń subskrybenta. Musisz tylko utworzyć dodatkowe wystąpienia klientów redis. client1 = redis.createClient(), client2 = redis.createClient()więc jeden może być w trybie abonenta, a drugi może wydawać regularne polecenia DB.
pubsub/*po prostu dodać pdo przykładu: wymienić subscibez psubscribei messagez pmessage.
Próbowaliśmy zrozumieć Redis Publish / Subscribe („ Pub / Sub ”) i wszystkie istniejące przykłady były albo nieaktualne, zbyt proste lub nie miały testów. Dlatego napisaliśmy kompletny czat w czasie rzeczywistym przy użyciu Hapi.js + Socket.io + Redis Pub / Sub Przykład z testami od końca do końca !
Komponent Pub / Sub to tylko kilka wierszy kodu node.js: https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40
Zamiast wklejać go tutaj ( bez żadnego kontekstu ), zachęcamy do zakupu / wypróbowania przykładu .
Zbudowaliśmy go za pomocą Hapi.js ale chat.jsplik jest de-sprzężony z Hapi i może łatwo być używane z podstawowego node.js serwer HTTP lub wyrażenia (itd.)
Obsługuj błędy redis, aby zatrzymać wyjście nodejs. Możesz to zrobić pisząc;
subcribe.on("error", function(){
//Deal with error
})
Myślę, że otrzymujesz wyjątek, ponieważ używasz tego samego klienta, który subskrybuje publikowanie wiadomości. Utwórz oddzielnego klienta do publikowania wiadomości, który może rozwiązać Twój problem.
Sprawdź acani-node w GitHub , zwłaszcza plik acani-node-server.js . Jeśli te linki są uszkodzone, poszukaj acani-chat-server wśród publicznych repozytoriów acani na GitHub .
Jeśli chcesz, aby to działało z socket.io 0.7 ORAZ zewnętrznym serwerem internetowym, musisz zmienić (oprócz staticProvider -> problem statyczny):
a) podać nazwę domeny zamiast localhost (np. var socket = io.connect ('http://my.domain.com:3000');) w pliku index.html
b) zmień HOST w app.js (tj. const HOST = 'my.domain.com';)
c) i dodaj gniazda w linii 37 pliku app.js (tj. „socket.sockets.on ('connection', function (client) {… '')
zgodnie z rozwiązaniem @alex . jeśli masz taki błąd, jak na wzmiankę @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.
następnie musisz najpierw zainstalować Redis . Sprawdź to:
const client = redis.createClient()w katalogu głównym app.js?