node
서비스를 기존 응용 프로그램에 통합하려는 경우 해당 응용 프로그램의 메시지를 메모리 대신 DB 인 node
으로 전달하기 위해 일종의 메시징 시스템을 사용하고 싶습니다. 명확성을 위해, 나는 rabbitmq를 사용할 수 있다고 가정합니다. redis를 사용해야하는 경우 rabbitmq 게시 및 해당 노드 측 구독 대신 게시를 사용하는 방법을 찾아야하지만 전체 솔루션이 동일 할 것이라고 생각합니다.
는 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
}
});
});
마지막으로 클라이언트가 옥에 여기에 (같이 대략 볼 것이다,하지만 내가 이미이 전을해서입니다 이 줄을 따라 쌓아 올리십시오) :