Programming/node.js2015. 2. 26. 21:15

node.js socket.io의 cluster 사용 참고사항


기본적으로 클라이언트가 transports: ['websocket'] 기반으로만 사용한다면 문제가 되지 않는다

하지만 XHR Polling 또는 JSONP Polling 사용시에는 

{"code":1,"message":"Session ID unknown"}

문제가 발생한다

폴링은 여러번 요청을 보내는데 여러 process중에 같은 process로 붙을 수 없어서 Session ID 찾을수 없는 듯하다


그래서

http://socket.io/docs/using-multiple-nodes/ 

메뉴얼 사이트에 보면 제시하는 방법이


1. NginX configuration

node.js에서 제공되는 cluster를 사용하지 않고 NginX를 앞단에 둔다

그리고 upstream 을 통해서 프록시 서버를 둔다 그리고 ip_hash 를 설정해서 같은 ip의 경우 같은 포트(즉같은프로세스)를 보도록 해서 문제를 해결한다

※ node.js socket.io는 데몬을 각각 포트별로 여러개 띄워야된다.


2. Using Node.JS Cluster

추가로 node.js Cluster 사용시에는 https://github.com/indutny/sticky-session 

(나도 아직 테스트 제대로 해보지 않았음)


3. Passing events between nodes

그리고 클러스터 구성시에 유저들간의 메세지(이벤트) 전달은 https://github.com/automattic/socket.io-redis

socket.io-redis이용해서 가능한 방법을 제공해주고있다

테스트해보니까 다른 node 프로세스로 붙어있지만 아래 명령어 실행시 이상없이 잘 동작한다.

socket.broadcast.emit  / 자신제외 전체유저

io.sockets.in(socket_id).emit / 특정유저에게메세지전달 

socket.broadcast.to(room_id).emit / 같은 룸에 입장된 유저에게 메세지전달

추가로 용량 처리가 많을 경우 detect_buffers 옵션을 true 해줘야됨

var redis  = require("redis");
var redisAdapter = require('socket.io-redis');
var pub = redis.createClient("/tmp/redis.sock",{ detect_buffers: true });
var sub = redis.createClient("/tmp/redis.sock",{ detect_buffers: true });
io.adapter( redisAdapter({pubClient: pub, subClient: sub}) );



※ socket.io 서비스 하기 위해서 유저별 socket.id를 관리하는 redis 와 서비스 비지니스 로직에 적절한 cluster 기능을 잘 구성해서 사용할 듯합니다.



해당 이슈로써 https://github.com/Automattic/socket.io/issues/1503 어느정도 방안에 대한 댓글을 볼수있다.


아래와 같은 것들도 있는 듯하다 아무쪼록 서비스 방향에 결정되면 좀더 연구해봐야될듯함

https://github.com/TopCloud/socketcluster

https://devcenter.heroku.com/articles/node-sessions 


Posted by 시니^^