2014-06-15 3 views
1

로그인 한 사용자의 경우에만 예를 들어 로그인했는지 여부를 알려주고 싶습니다. 새로운 알림.redis에 가입 한 nodejs 푸시 알림

예를 들어 회원이 비공개 메시지를 보냈다고 가정 할 때 사용자에게 새로운 메시지가 있음을 알리고 싶습니다 (페이지를 새로 고치지 않은 것으로 가정).

Nodejs와 redis를 사용하면 어떻게해야합니까?

참고 : 사용자에게 새 메시지가 있다고 말하는 작은 json 만 보내면됩니다. 내가 생각하는 것을 다음과 같이

워크 플로는 다음과 같습니다

1. user is logged in, a new message is sent to them. 
    2. somehow using nodejs and redis and long-polling, nodejs communicates back to the logged in users browser they have a pending message. 
    3. when nodejs sends this push notification, I then call another javascript function that will call a rest service to pull down additional json with the message. 

내가 통합하고 nodejs를 기존 응용 프로그램에, 그래서 난 단지 통지하고 안하고에 대한 책임 nodejs와 가능한 한 간단하게 유지하려면 추가 논리.

누군가 내가 어떻게해야 할지를 대략적으로 설명 할 수 있습니까? 어떻게 든 redis를 사용해야합니까 http://redis.io/topics/pubsub?
페이지에 대해 읽은 후에도 어떻게 작동하는지 잘 모르겠습니다.

답변

5

node 서비스를 기존 응용 프로그램에 통합하려는 경우 해당 응용 프로그램의 메시지를 메모리 대신 DB 인 node으로 전달하기 위해 일종의 메시징 시스템을 사용하고 싶습니다. 명확성을 위해, 나는 rabbitmq를 사용할 수 있다고 가정합니다. redis를 사용해야하는 경우 rabbitmq 게시 및 해당 노드 측 구독 대신 게시를 사용하는 방법을 찾아야하지만 전체 솔루션이 동일 할 것이라고 생각합니다.

  • rabbitmq 서버 메시지를 보낼 수있는 외부 응용 프로그램에서
  • rabbitmq 라이브러리합니다 (redis에 대한 동일에 대한 설치의 복잡성), 대부분의 언어가 지원됩니다
  • rabit.js 모듈 :

    당신은 다음과 같은 모듈이 필요합니다 node에 메시지를 구독하거나 외부 응용 프로그램에 다시 통신하려면

  • socket.io용 모듈 나는 또한 외부 응용 프로그램과 node 서버 모두가 (레디 스 될 수 있습니다) 일부 공유 DB, node 클라이언트 세션 정보에 액세스 할 수 있다고 가정합니다

node 서버와 클라이언트 간의 실시간 연결을 설정하기 (예 : node에 대해서는 redis-session-store). 이렇게하면 sessionId을 사용하여 세션에있는 사용자가 로그인 한 경우 및 특정 사용자가 외부 앱을 통해 알림을 보내야하는 경우 메시지 유효성을 확인할 수 있습니다.

이 당신의 스택 (무광택)처럼 보이게하는 방법입니다 :

가 시작/주어진 sessionId에 대한 메시지 전송을 중지 할 필요가 외부 응용 프로그램을 알리기 위해 node에 게시자를 정의합니다.나는 주어진 sessionId에 대해 사용자 정보가 공유 DB에서 양쪽 ( node 또는 외부 응용 프로그램)으로 복구 될 수 있으며 사용자는 유효성을 검사 할 수 있다고 가정합니다 (여기서는 간단하게 session.authenticated_user을 확인). 또한 사용자의 수신 메시지를 듣고 가입자를 정의

var context = require('rabbit.js').createContext(); 

var pub = context.socket('PUB'); 
var sub = context.socket('SUB'); 

가 클라이언트로 node 서버에서 socket.io 연결 (들)을 정의합니다. 곧 클라이언트의 웹 페이지가 다시로드되고 io.connect()이 호출되면 아래 코드가 실행됩니다 (답안의 마지막 부분 참조). 새 연결이 설정되면 사용자가 로그인했는지 (해당 자격 증명이 세션에 있음을 의미) 유효성을 검사하고, 소켓 처리기를 등록하고 외부 응용 프로그램에 알림을 게시하여 sessionId에 대한 메시지를 보내기 시작합니다. 이 코드는 로그인/로그 아웃시 페이지 새로 고침을 가정합니다 (따라서 새로운 socket.io 세션). 그렇지 않은 경우 클라이언트에서 해당 socket.io 메시지를 node으로 내보내고 새 연결에 대한 작업과 동일한 방법으로 아래 메서드에서 처리기를 등록하십시오 (이 예제의 범위를 벗어납니다) :

var sessionStore = undefined; // out-of-scope: define redis-session-store or any other store 

var cookie = require("cookie"), 
    parseSignedCookie = require('connect').utils.parseSignedCookie; 

// will store a map of all active sessionIds to sockets 
var sockets = {}; 

// bind socket.io to the node http server 
var io = require('socket.io').listen(httpServer); 

// assumes some config object with session secrect and cookie sid 
io.sockets.on("connection", function(socket) { 
    if (socket.handshake.headers.cookie) { 
     var cks = cookie.parse(socket.handshake.headers.cookie); 
     var sessionId = parseSignedCookie(cks[config.connectSid], config.sessionSecret); 

     // retrieve session from session store for sessionId 
     sessionStore.get(sessionId, function(err, session) { 
      // check if user of this session is logged in, 
      // define your elaborate method here 
      if (!err && session.authenticated_user) { 
       // define cleanup first for the case when user leaves the page 
       socket.on("disconnect", function() { 
        delete sockets[sessionId]; 
        // notify external app that it should STOP publishing 
        pub.connect('user_exchange', function() { 
         pub.write(JSON.stringify({sessionId: sessionId, action: 'stop', reason: 'user disconnected'}), 'utf8'); 
        }); 
       }); 

       // store client-specific socket for emits to the client 
       sockets[sessionId] = socket; 

       // notify external app that it should START publishing 
       pub.connect('user_exchange', function() { 
        pub.write(JSON.stringify({sessionId: sessionId, action: 'start'}), 'utf8'); 
       }); 
      } 
     }); 
    } 
}); 
메시지를 잡을 클라이언트로 방출하는 rabbitmq 교환

연결 가입자 :

sub.connect('messages_exchange', function() { 
    sub.on("readable", function() { 
     // parse incoming message, we need at least sessionId 
     var data = JSON.parse(sub.read()); 
     // get socket to emit for this sessionId 
     var socket = sockets[data.sessionId]; 
     if (socket) { 
      socket.emit("message", data.message); 
     } else { 
      // notify external app that it should STOP publishing 
      pub.connect('user_exchange', function() { 
       pub.write(JSON.stringify({sessionId: sessionId, action: 'stop', reason: 'user disconnected'}), 'utf8'); 
      }); 
      // further error handling if no socket found 
     } 
    }); 
}); 

마지막으로 클라이언트가 옥에 여기에 (같이 대략 볼 것이다,하지만 내가 이미이 전을해서입니다 이 줄을 따라 쌓아 올리십시오) :