जब डेटा मान बदलते हैं, तो क्लाइंट को सूचित करने के लिए नोडज के साथ रेडिस पब्लिक / SUBSCRIBE का उपयोग कैसे करें?


99

मैं NodeJS और Redis के साथ एक घटना-संचालित प्रकाशित / सदस्यता आवेदन लिख रहा हूं। मुझे एक उदाहरण की आवश्यकता है कि वेब क्लाइंट को कैसे सूचित करें जब Redis में डेटा मान बदलते हैं।

जवाबों:


123

OLD केवल एक संदर्भ का उपयोग करें

निर्भरता

मीडिया फायर से एक्सप्रेस , सॉकेट.आईओ , नोड_रेडिस और कम से कम नमूना कोड का उपयोग करता है ।

नोड स्थापित करें। js + npm (गैर रूट के रूप में)

पहले आपको (यदि आपने अभी तक ऐसा नहीं किया है) नोड ( js ) + npm को 30 सेकंड में स्थापित करें (सही तरीके से क्योंकि आपको npm को रूट के रूप में नहीं चलाना चाहिए ):

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

निर्भरता स्थापित करें

नोड + एनपीएम स्थापित करने के बाद आपको जारी करके निर्भरताएं स्थापित करनी चाहिए:

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

नमूना डाउनलोड करें

आप मीडियाफेयर से पूरा नमूना डाउनलोड कर सकते हैं ।

अनज़िप पैकेज

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

ब्राउज़र प्रारंभ करें

यदि आप google chrome शुरू करते हैं तो सबसे अच्छा है (क्योंकि websockets समर्थन, लेकिन आवश्यक नहीं)। http://localhost:3000नमूना देखने के लिए जाएँ (शुरुआत में आपको PubSubशीर्षक के रूप में कुछ भी नहीं दिखता है )।

लेकिन publishचैनल पर pubsubआपको एक संदेश देखना चाहिए। नीचे हम "Hello world!"ब्राउज़र पर प्रकाशित करते हैं।

से ./redis-cli

publish pubsub "Hello world!"

आपको const client = redis.createClient()app.js के मूल में क्यों आवश्यकता है?
आकाश

आपको कॉन्स्ट का उपयोग करने की आवश्यकता नहीं है। var का उपयोग भी किया जा सकता है और शायद मुझे इसके बजाय होना चाहिए क्योंकि const केवल नए जावास्क्रिप्ट इंजनों में उपलब्ध है। इसके अलावा यह रेखा सुनिश्चित करती है कि हम रेडिस सर्वर से जुड़े हैं जिसका उपयोग हम इस उदाहरण में करते हैं।
अल्फ्रेड

5
नमूना बहुत पुराना है इसलिए नवीनतम सॉकेट के साथ अद्यतित नहीं है ।io/express मॉड्यूल और शायद नोड भी। js. मैं कोड अपडेट करने का प्रयास करूंगा। इस कोड के साथ एक और बड़ी समस्या यह भी है कि यह प्रत्येक जुड़े उपयोगकर्ता के लिए एक और रेडिस कनेक्शन खोलता है। इसके बजाय केवल उस पर होना चाहिए। मुझे पहले काम करना है, लेकिन उसके बाद मैं कोड को अपडेट करने की कोशिश करता हूं।
अल्फ्रेड

1
बहुत अच्छा। मुझे अभी भी लगता है कि कुछ सुधारों के लिए जगह है जब मेरे पास समय होगा जब मैं ऑनलाइन डालूंगा। लेकिन अभी मैं वास्तव में कड़ी मेहनत कर रहा हूं: $।
अल्फ्रेड

1
मुझे लगता है कि subscribe.on सॉकेट के बाहर होना चाहिए। ('कनेक्शन') कई सबस्क्राइबर्स से बचने के लिए ब्लॉक /
zubinmehta

26

यहाँ कई निर्भरता के बिना एक सरल उदाहरण है। आपको अभी भी जरूरत हैnpm install hiredis redis

नोड जावास्क्रिप्ट:

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

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

... एक pubsub.js फ़ाइल में रखें और चलाएं node pubsub.js

redis-cli में:

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

जो प्रदर्शित होना चाहिए: pubsub: Hello Wonky!टर्मिनल रनिंग नोड में! बधाई!

अतिरिक्त 4/23/2013: मैं यह भी नोट करना चाहता हूं कि जब कोई ग्राहक पब / सब चैनल को सब्सक्राइब करता है तो वह सब्सक्राइबर मोड में चला जाता है और सब्सक्राइबर कमांड तक सीमित रहता है। आपको केवल रेडिस क्लाइंट के अतिरिक्त इंस्टेंसेस बनाने की आवश्यकता होगी। client1 = redis.createClient(), client2 = redis.createClient()तो एक ग्राहक मोड में हो सकता है और दूसरा नियमित डीबी कमांड जारी कर सकता है।


यहां जब हम रेडिस में डेटा जोड़ते हैं, तो क्या मुझे सम्मिलित करने की सूचना प्राप्त करने के लिए पब्लसब को प्रकाशित करना चाहिए?
ईशा

1
@ यदि आप क्या करने की जरूरत है, तो हाँ। यदि आपको कई आदेशों को कम से कम चलाने की आवश्यकता है, तो आपको लेनदेन पर भी ध्यान देना चाहिए: redis.io/commands/exec
nak

@nak यह एक GO में आकर्षण की तरह काम करता है :) कुछ उपयोगकर्ताओं को पहले से स्थापित नहीं होने पर 'डबल-एंड-कतार' स्थापित करने की आवश्यकता हो सकती है।
मंजीत

1
यह भी लायक उल्लेख करने के लिए कि आप वाइल्डकार्ड का उपयोग करना चाहते हैं, उदाहरण के लिए, करने के लिए सदस्यता pubsub/*सिर्फ जोड़ने pउदाहरण के लिए: की जगह subscibeके साथ psubscribeऔर messageसाथ pmessage
लियोशा बाकसिन

7

पूर्ण Redis पब / उप उदाहरण ( Hapi.js और Socket.io का उपयोग करके वास्तविक समय चैट )

हम Redis Publish / Subscribe (" पब / सब ") को समझने की कोशिश कर रहे थे और सभी मौजूदा उदाहरण या तो पुराने थे, बहुत सरल या कोई परीक्षण नहीं था। इसलिए हमने एंड-टू-एंड टेस्ट के साथ Hapi.js + Socket.io + Redis Pub / Sub उदाहरण का उपयोग करके एक पूर्ण वास्तविक-समय चैट लिखा !

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

पब / सब कंपोनेंट केवल नोड.जेएस कोड की कुछ पंक्तियाँ है: https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40

यहां ( बिना किसी संदर्भ के ) इसे चिपकाने के बजाय हम आपको उदाहरण के लिए चेकआउट / प्रयास करने के लिए प्रोत्साहित करते हैं ।

हमने इसे Hapi.js का उपयोग करके बनाया था लेकिन chat.jsफ़ाइल Hapi से डी- कपल है और इसे आसानी से एक मूल नोड के साथ प्रयोग किया जा सकता है। http सर्वर या एक्सप्रेस (आदि)


क्या आपके पास यह उदाहरण है?
गिक्सी जूल

@ Gixty हमने Hapi.js का उपयोग करते हुए उदाहरण लिखा है क्योंकि अन्य सभी उदाहरण वहां Express.js का उपयोग करते हैं ... जैसा कि पोस्ट में उल्लेख किया गया है, इसे किसी भी अन्य Node.js ढांचे में पोर्ट करने के लिए इसका तुच्छ (बस एक्सप्रेस ऐप में पास करें chat.js init कोड के लिए श्रोता) और यह बिल्कुल वैसा ही काम करता है। ps: यदि आप हापी के लिए नए हैं तो देखें: github.com/nelsonic/learn-hapi
nelsonic

4

नोडज को बाहर निकलने से रोकने के लिए रेडिस त्रुटियों को संभालें। आप यह लिखकर कर सकते हैं;

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

मुझे लगता है कि आपको अपवाद मिलता है क्योंकि आप उसी ग्राहक का उपयोग कर रहे हैं जो संदेशों को प्रकाशित करने के लिए सदस्यता लेता है। संदेश प्रकाशित करने के लिए एक अलग क्लाइंट बनाएँ और जो आपकी समस्या को हल कर सके।



2

यदि आप इसे सॉकेट के साथ काम करना चाहते हैं। 0.7 और एक बाहरी वेबसर्वर जिसे आपको बदलने की आवश्यकता है (इसके अलावा स्थैतिक सर्वर -> स्थिर मुद्दा):

a) डोमेन नाम प्रदान करें index.html में स्थानीय (यानी var सॉकेट = io.connect ('http://my.domain.com:3000') के बजाय );

b) app.js में HOST बदलें (यानी const HOST = 'my.domain.com';)

c) और app.js (यानी 'socket.sockets.on (' कनेक्शन ', फंक्शन (क्लाइंट) {...') की पंक्ति 37 में सॉकेट जोड़ें



0

@alex समाधान के अनुसार । अगर आपको @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.

फिर आपको पहले Redis स्थापित करने की आवश्यकता है । इसकी जांच करें:

http://redis.io/download

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.