Redis PUBLISH / SUBSCRIBE'ı istemcileri veri değerleri değiştiğinde bilgilendirmek için nodejs ile nasıl kullanabilirim?


99

NodeJS ve Redis ile olay odaklı bir yayınlama / abone olma uygulaması yazıyorum. Redis'teki veri değerleri değiştiğinde web istemcilerini nasıl bilgilendireceğime dair bir örneğe ihtiyacım var.

Yanıtlar:


123

ESKİ yalnızca referans kullanır

Bağımlılıklar

kullanımları ifade , socket.io , node_redis ve son ama en az örnek kod medya ateşten.

Node.js + npm'yi yükleyin (kök olmayan olarak)

Öncelikle (bunu henüz yapmadıysanız) 30 saniyede node.js + npm'yi yüklemelisiniz (doğru yol çünkü npm'yi kök olarak ÇALIŞTIRMAMALISINIZ ):

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

Bağımlılıkları yükleyin

Düğüm + npm'yi kurduktan sonra, aşağıdakileri vererek bağımlılıkları yüklemelisiniz:

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

Örnek indirin

Mediafire'dan eksiksiz bir örnek indirebilirsiniz .

Paketi açın

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

Zip'in içinde ne var

./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>

Sunucuyu başlat

cd pbsb    
node app.js

Tarayıcıyı başlatın

En iyisi google chrome'u başlatırsanız (websockets desteği nedeniyle, ancak gerekli değildir). http://localhost:3000Örneği görmek için ziyaret edin (başlangıçta PubSubbaşlıktan başka bir şey görmüyorsunuz ).

Ancak publishkanalda pubsubbir mesaj görmelisiniz. Aşağıda "Hello world!"tarayıcıya yayınlıyoruz .

./Redis-cli'den

publish pubsub "Hello world!"

neden const client = redis.createClient()app.js'nin köküne ihtiyacınız var ?
Akasha

const kullanmanıza gerek yok. var da kullanılabilir ve bunun yerine sahip olmalıyım çünkü const yalnızca daha yeni javascript motorlarında kullanılabilir. Ayrıca bu satır, bu örnekte kullandığımız redis sunucusuna bağlı olmamızı sağlar.
Alfred

5
Örnek çok eskidir, bu nedenle en son socket.io/express modülleri ve hatta node.js ile güncel değildir. Kodu güncellemeye çalışırdım. Bu kodla ilgili başka bir büyük sorun da, bağlı her kullanıcı için başka bir redis bağlantısı açmasıdır. Bunun yerine sadece açık olmalıdır. Önce çalışmam gerekiyor, ancak ondan sonra kodu güncellemeye çalışıyorum.
Alfred

1
Çok iyi. Hala zamanım olduğunda internete koyacağım bazı iyileştirmeler için yer olduğunu düşünüyorum. Ama şu anda gerçekten çok çalışıyorum: $.
Alfred

1
Bence subscribe.on, birden fazla aboneden kaçınmak için socket.on ('bağlantı') bloğunun dışında olmalı /
zubinmehta

26

İşte bu kadar bağımlılık içermeyen basitleştirilmiş bir örnek. Hala ihtiyacın varnpm install hiredis redis

Düğüm JavaScript:

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

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

... bunu bir pubsub.js dosyasına koyun ve node pubsub.js

redis-cli'de:

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

görüntülenecek olan: pubsub: Hello Wonky!terminal çalışan düğümde! Tebrikler!

Ek 4/23/2013: Bir müşteri bir pub / sub kanala abone olduğunda abone moduna girer ve abone komutlarıyla sınırlı olduğunu da belirtmek isterim. Yalnızca ek redis istemcileri örneği oluşturmanız gerekir. client1 = redis.createClient(), client2 = redis.createClient()böylece biri abone modunda olabilir ve diğeri normal DB komutları verebilir.


Burada redise veri eklediğimizde, ekleme bildirimini almak için yayınla pubsub çalıştırmalı mıyım?
IshaS

1
@IshaS, yapmanız gereken buysa, evet. Birden fazla komutu atomik olarak çalıştırmanız gerekirse, işlemleri de incelemelisiniz: redis.io/commands/exec
nak

@nak Bu, bir GO'da cazibe gibi çalıştı :) Bazı kullanıcıların, önceden kurulmamışsa 'çift uçlu kuyruk' yüklemesi gerekebilir.
Manjeet

1
Örneğin, joker karakterler kullanmak istiyorsanız, yalnızca örneğe pubsub/*eklemek piçin abone olun : subscibeile psubscribeve messageile değiştirin pmessage.
Liosha Bakoushin

7

Komple Redis Pub / Sub Örnek ( Gerçek Zamanlı Sohbet Hapi.js & Socket.io kullanarak)

Redis Yayınla / Abone Ol'u (" Pub / Sub ") anlamaya çalışıyorduk ve mevcut tüm örnekler ya güncelliğini yitirdi, çok basitti ya da hiç testi yoktu. Bu nedenle, Uçtan Uca Testlerle Hapi.js + Socket.io + Redis Pub / Sub Örneğini kullanarak Eksiksiz Gerçek Zamanlı Sohbet yazdık !

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

Pub / Sub bileşeni yalnızca birkaç satırlık node.js kodudur: https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40

Buraya yapıştırmak yerine ( herhangi bir bağlam olmadan ) örneği kontrol etmenizi / denemenizi öneririz .

Biz kullanarak inşa Hapi.js ama chat.jsdosyasıdır -de birleştiğinde Hapi gelen edebilir kolayca bir ile kullanılabilir temel node.js http sunucusu veya ekspres (vs)


ekspres ile bu örnek var mı?
Gixty

@Gixty, örneği Hapi.js kullanarak yazdık, çünkü oradaki diğer tüm örnekler Express.js kullanıyor ... yayında belirtildiği gibi, başka bir Node.js çerçevesine taşımak önemsizdir (sadece ekspres uygulamada / dinleyici chat.js başlatma kodu) ve tamamen aynı şekilde çalışır. ps: Hapi.js'de yeniyseniz bkz: github.com/nelsonic/learn-hapi
nelsonic

4

Nodej'lerin çıkmasını durdurmak için redis hatalarını işleyin. Bunu yazarak yapabilirsiniz;

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

Mesajları yayınlamak için abone olan aynı müşteriyi kullandığınız için istisnayı aldığınızı düşünüyorum. Mesajları yayınlamak için ayrı bir müşteri oluşturun ve bu sorununuzu çözebilir.



2

Bunun socket.io 0.7 VE harici bir web sunucusu ile çalışmasını istiyorsanız, değiştirmeniz gerekir (staticProvider -> statik sorunun yanı sıra):

a) index.html'de localhost (yani var socket = io.connect ('http://my.domain.com:3000');) yerine alan adını sağlayın

b) app.js'de HOST'u değiştirin (yani const HOST = 'alanim.com';)

c) ve app.js'nin 37. satırına soketler ekleyin (ör. 'socket.sockets.on (' bağlantı ', işlev (istemci) {…')



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.