데이터 값이 변경되면 클라이언트에게 알리기 위해 nodejs와 함께 redis PUBLISH / SUBSCRIBE를 사용하는 방법은 무엇입니까?


99

NodeJS 및 Redis를 사용하여 이벤트 기반 게시 / 구독 애플리케이션을 작성하고 있습니다. Redis의 데이터 값이 변경 될 때 웹 클라이언트에 알리는 방법에 대한 예제가 필요합니다.

답변:


123

OLD는 참조 만 사용

의존성

용도는 표현 , Socket.IO에 , node_redis 는 AND 마지막으로 샘플 코드 미디어 화재를.

node.js + npm 설치 (루트가 아님)

먼저 (아직 수행하지 않은 경우) 30 초 내에 node.js + npm을 설치 해야합니다 ( 루트로 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

종속성 설치

node + npm을 설치 한 후 다음을 실행하여 종속성을 설치해야합니다.

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

샘플 다운로드

mediafire 에서 전체 샘플을 다운로드 할 수 있습니다 .

패키지 압축 해제

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

zip 내부 내용

./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 크롬을 시작하는 것이 가장 좋습니다 (웹 소켓 지원 때문에 필요하지 않음). http://localhost:3000샘플을 보려면 방문 하십시오 (처음 PubSub에는 제목으로 만 표시 됩니다).

그러나 publish채널 pubsub에 메시지가 표시되어야합니다. 아래 "Hello world!"에서 브라우저에 게시 합니다.

./redis-cli에서

publish pubsub "Hello world!"

const client = redis.createClient()app.js의 루트에 필요합니까?
Akasha

const를 전혀 사용할 필요가 없습니다. var도 사용할 수 있으며 const는 최신 자바 스크립트 엔진에서만 사용할 수 있기 때문에 대신 사용해야 할 수도 있습니다. 또한이 라인은이 예제에서 사용하는 redis 서버에 연결되어 있는지 확인합니다.
Alfred

5
샘플은 매우 오래되었으므로 최신 socket.io/express 모듈과 어쩌면 node.js로도 최신이 아닙니다. 코드를 업데이트하려고합니다. 이 코드에는 연결된 각 사용자에 대해 또 다른 redis 연결을 여는 또 다른 큰 문제가 있습니다. 대신 켜져 있어야합니다. 먼저 작업해야하지만 그 후에 코드를 업데이트하려고합니다.
Alfred

1
아주 좋아요. 나는 여전히 시간이있을 때 온라인에 올릴 몇 가지 개선의 여지가 있다고 생각합니다. 하지만 지금은 정말 열심히하고 있어요 : $.
알프레드

1
나는 subscribe.on 여러 구독 / 방지하기 위해 socket.on ( '연결') 블록 외부에 있어야한다고 생각
zubinmehta

26

다음은 많은 종속성이없는 단순화 된 예입니다. 당신은 여전히 ​​필요합니다npm install hiredis redis

노드 JavaScript :

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 : 또한 클라이언트가 pub / sub 채널을 구독하면 구독자 모드로 전환되고 구독자 명령으로 제한된다는 점에 유의하고 싶습니다. redis 클라이언트의 추가 인스턴스를 생성하기 만하면됩니다. client1 = redis.createClient(), client2 = redis.createClient()따라서 하나는 구독자 모드에 있고 다른 하나는 일반 DB 명령을 실행할 수 있습니다.


여기서 redis에 데이터를 추가 할 때 삽입 알림을 받으려면 publish pubsub를 실행해야합니까?
IshaS

1
그게 당신이해야 할 일이라면 @IshaS, 예. 여러 명령을 원자 적으로 실행해야하는 경우에도 트랜잭션을 조사해야합니다. redis.io/commands/exec
nak

@nak 이것은 하나의 GO에서 매력처럼 작동했습니다. 일부 사용자는 아직 설치되지 않은 경우 'double-ended-queue'를 설치해야 할 수 있습니다.
Alex

1
또한 가치가 와일드 카드를 사용하려는 경우, 예를 들어, 구독 말할 것도 pubsub/*바로 추가 p교체 : 예에 subscibepsubscribemessage함께 pmessage.
Liosha Bakoushin

7

완전한 Redis Pub / Sub 예제 ( Hapi.js 및 Socket.io를 사용한 실시간 채팅 )

우리는 Redis Publish / Subscribe ( " Pub / Sub ") 를 이해하려고 노력 했으며 기존의 모든 예제는 오래되었거나 너무 간단하거나 테스트가 없었습니다. 그래서 우리는 Hapi.js + Socket.io + Redis Pub / Sub 예제와 종단 간 테스트를 사용하여 완전한 실시간 채팅을 작성했습니다 !

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

Pub / Sub 구성 요소는 몇 줄의 node.js 코드입니다. https://github.com/dwyl/hapi-socketio-redis-chat-example/blob/master/lib/chat.js#L33-L40

오히려 (여기에 붙여 넣기보다 어떤 맥락없이 ) 우리는 장려 / 체크 아웃에 당신을 시도 .

우리는 사용하여 내장 Hapi.js 하지만 chat.js파일은 드 결합 게요!에서 할 수 있습니다 쉽게 와 함께 사용할 수 기본 Node.js를 HTTP 서버 또는 표현 (등)


Express에이 예가 있습니까?
Gixty

@Gixty 우리는 Hapi.js를 사용하여 예제를 작성했습니다. 왜냐하면 다른 모든 예제는 Express.js를 사용하기 때문입니다 ... 게시물에서 언급했듯이 다른 Node.js 프레임 워크로 이식하는 것은 간단합니다 (간단히 express app / chat.js init 코드에 대한 리스너)와 정확히 동일하게 작동합니다. PS : 당신이 Hapi.js를 처음 사용하는 경우 참조 : github.com/nelsonic/learn-hapi를
nelsonic

4

redis 오류를 처리하여 nodejs가 종료되지 않도록합니다. 당신은 글을 써서 이것을 할 수 있습니다;

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

메시지 게시를 구독하는 동일한 클라이언트를 사용하고 있기 때문에 예외가 발생한다고 생각합니다. 메시지 게시를위한 별도의 클라이언트를 생성하면 문제를 해결할 수 있습니다.



2

socket.io 0.7 외부 웹 서버 에서이 작업을 수행 하려면 변경해야합니다 (staticProvider-> 정적 문제 제외) :

a) 도메인 이름 제공 index.html에 localhost 대신 (예 : var socket = io.connect ( 'http://my.domain.com:3000');)을 제공합니다.

b) app.js에서 HOST 변경 (예 : const HOST = 'my.domain.com';)

c) app.js의 37 행 에 소켓 을 추가합니다 (예 : 'socket.sockets.on ('connection ', function (client) {…')



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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.