nanha
11/6/2011 - 3:06 AM

[node.js socket.io] Namespace+Room기반 메신저 플젝 진행중. 1:1 대화중 서로 대화 요청시 대화창은 1개만 떠야한다. !!

[node.js socket.io] Namespace+Room기반 메신저 플젝 진행중. 1:1 대화중 서로 대화 요청시 대화창은 1개만 떠야한다. !!

/**
 * 1:1채팅중에 참여중인 namespace+room 목록

■ 요구조건
- 서로의 대화명을 클릭시 메신저 창이 따로 보여지면 안됨.
- 자신이 대화중인지를 클라이언트 혹은 서버에서 판단할 필요있음.

■ 해결방법
- sessionid를 공유변수로 설정할려 했으나, socket.io lib 에 뭔가 있을거 같은 생각. ㅋ
- https://github.com/LearnBoost/socket.io/blob/master/lib/manager.js 에 많은 정보가 들어있음.

■ 전제조건
방번호는 require('node-uuid')() 으로 생성한 상태

■ source
var rid = this.getRidOnAndOn(상대방 sessionid, socket.id);
rid 값이 존재할시 방을 만들필요없고, join 만 하면 된다.

 *
 * @param Number otherSid - 상대방의 sessionid
 * @param Number sid      - 자신의 sessionid
 * @return String
 */
ChatManager.prototype.getRidOnAndOn = function(otherSid, sid) {
    // 1:1 대화상태인지
    var isOneAndOneRoom = function(room) {
        return room && room.length == 2;
    };
    // room에 상대방과 내가 이미 포함되어 있는지
    var isJoinRoomTogether = function(room, otherSid, sid) {
        return room.indexOf(sid) != -1 && room.indexOf(otherSid) != -1;
    };
    // nsp 값으로부터 roomid 값만 추출
    var getRidFromNS = function(nsp) {
        return nsp.slice(nsp.lastIndexOf('/') + 1);
    };

    // this.nsp 는 this.nsp = io.of('/' + nsp).on('connection' ... 
    var result = false,
        stack = [],
        rooms = this.nsp.manager.rooms;
        roomClients = this.nsp.manager.roomClients[sid];

    for (var nsp in roomClients) {
        // roomClients 에서 '', '/NS' 제외
        // '/NS/RoomID' 값만 추출
        if (nsp.lastIndexOf('/') <= 0) continue;

        if (roomClients[nsp] == true) stack.push(nsp);
    }

    for (var i in stack) {
        // 1:1대화중인지, 내가 같이 포함되어 있는지 판단
        if (isOneAndOneRoom(rooms[stack[i]]) && isJoinRoomTogether(rooms[stack[i]], otherSid, sid)) {
            // 이미 나는 대화중임. 방을 만들필요없이 해당 방에 JOIN
            return getRidFromNS(stack[i]);
        }
    }

    // 방에 포함되어 있지 않음. require('node-uuid')() 방 만듬.
    return result;
};