본문 바로가기

Develop/NodeJS

[NodeJS] redis 이용한 pub/sub 구현

nodejs에서 socket.io를 쓸때를 비롯해 각 프로세스간의 데이터 공유가 필요할 경우.
redis의 pub/sub를 사용하면 간단하게 서로간의 통신을 해줄수 있음.

필요한 부분만 딱 적어보자면..


var pub = redis.createClient(),
  sub = redis.createClient();

// 비밀번호가 있을경우
pub.auth([password], function(e){if(e) console.log(e);});
sub.auth([password], function(e){if(e) console.log(e);});

var clientSocket = new Object();

var server = http.createServer(app);                                 
server.listen(app.get('port'), function(){                           
  console.log('Express server listening on port ' + app.get('port'));
});                                                                  

var io = require('socket.io').listen(server);

io.set('log level', 0);

io.socket.on('connection', function(socket){
  socket.on('login', function(data){
    if(clientSocket.[data.client_id] == undefined){
      //subscribe 기능 추가 해주는 부분.
      // 여기서 사용해주는 값은 추후 subscribe에서 받을때 사용될 channel이 됨.
      sub.subscribe('publishData');
    }
    clientSocket[data.client_id] = socket;
  });
  socket.on('disconnect', function(){
    (.......)
  });
  sub.on('message', function(channel, data){
    if(channel == 'publishData'){
      (.................)
    }
   });
   socket.on('chat', function(data){
    if(clientSocket[data.client_id] == undefined){
      // publish해줄 채널
      pub.publish('publishData', data);
    }else{
      clientSocket[data.client_id].emit('ack', data);
    }
   });  
});

위 소스는 물론 동작하지 않을지 모르지만..흐름은 이런식임.


위 소스의 설명을 풀어 놓자면...

우선 connection이 맺어지면 해당 socket정보를 가지고 있음.

이 정보는 나중에 요청이 왔을때 내가 해당하는 녀석과의 connection정보를 가지고있는지 나타내줌.

이후 요청이 왔을경우 받아야할 녀석을 connection정보들에서 찾아서 없을경우 publish를 날려줌.

publish를 날리게 되면 redis서버를 subscribe하고있던 녀석이

해당 channel의 내용을 받아와서 다시 로직이 돌게됨.

이때 채널을 비교해서 publish한 녀석과 동일한 절차를 거쳐 내당 연결이 있는지 체크해서 없으면 끝.

(만약 최초 publish한 서버와 다른 또다른 redis서버와 연결이 있다면 publish)

연결이 있으면 해당되는 녀석에게 emit해주면됨.


이렇게 해주면 서로 다른 node서버에 붙어있는 녀석에게도 push를 줄수가 있음.