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:3000
aby zobaczyć próbkę (na początku nie widzisz niczego, ale PubSub
jako tytuł).
Ale na publish
kanale pubsub
powinieneś 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ć p
do przykładu: wymienić subscibe
z psubscribe
i message
z 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.js
plik 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?