복붙노트

[REDIS] 어떻게 사용되어야 하는가? Socket.io 객실 또는 레디 스 펍 서브?

REDIS

어떻게 사용되어야 하는가? Socket.io 객실 또는 레디 스 펍 서브?

아주 간단한 질문입니다. 내 백엔드로 nodejs를 사용하여 실시간으로 게임을 구축하고 거기에 어떤 정보가 하나 더 신뢰할 수있는 가능하며, 하나가 더 효율적이다 궁금 무엇입니까? 나는 주로 내 코드에 걸쳐있는 레디 스 및 Socket.io를 사용하고 있습니다. 나는 Socket.io의 객실을 활용해야한다 또는 내가 레디 스 '술집 서브를 사용하여 더 나을 것입니다 여부를 알고 싶어 그래서?

최신 정보: 그냥 당신이 socket.io 객실에 걸쳐 레디 스 펍 / 하위를 사용할 수 있습니다 이유는 매우 중요한 이유가 깨달았다. Socket.io 객실 사용하면 (브라우저) 클라이언트는 실제로 메시지를받을 (서버 레디 스 ~) 클라이언트입니다 레디 스에 메시지를받을, 청취자에 게시 할 때. 각 클라이언트에 정보를 특정의 모든 (서버) 클라이언트를 통보하고 어쩌면 브라우저 클라이언트에 전달하기 전에 일부 처리를 수행하려는 경우 따라서, 당신은 더 나은 레디 스를 개시한다. 레디 스를 사용하여 당신은 각 사용자 개별 데이터를 생성하는 이벤트를 해고 할 수있는 당신이 실제로 그들을 통해 모든 사용자에게 한 번에 고유 한 데이터, 다음 루프를 생성하고 그들에게 거의 패배 개별 데이터를 전송해야 Socket.IO에와 같이 객실의 목적, 나를 위해 적어도.

불행하게도 나의 목적을 위해 나는 지금 레디 스에 붙어있다.

업데이트 2 : .... 플러그인 만 2 레디 스 연결을 사용하지만 여전히 개별 클라이언트 처리를 허용, 아래의 답을보고 개발까지 종료

해결법

  1. ==============================

    1.레디 스 펍 / 서브 경우 모든 클라이언트가 레디 스에 직접 액세스 할 중대하다. 여러 노드 서버가있는 경우, 하나는 다른 사람에게 메시지를 푸시 할 수 있습니다.

    레디 스 펍 / 서브 경우 모든 클라이언트가 레디 스에 직접 액세스 할 중대하다. 여러 노드 서버가있는 경우, 하나는 다른 사람에게 메시지를 푸시 할 수 있습니다.

    당신은 또한 브라우저에서 클라이언트가있는 경우에, 당신은 클라이언트에 서버에서 푸시 데이터에 다른 뭔가를해야하고,이 경우, socket.io는 중대하다.

    당신은 레디 스 저장소와 socket.io를 사용하는 경우 이제, socket.io는 서버간에 메시지를 전달하기 위해 후드 레디 스 펍 / 서브를 사용하고, 서버는 클라이언트에 메시지를 전달합니다.

    레디 스 저장소로 구성 socket.io와 socket.io 객실을 사용 그래서 아마 당신을위한 간단합니다.

  2. ==============================

    2.나는 그것을 위해 사용을 찾을 수 밖에 일반적으로 생각 된 사람에서 작동합니다 많은 술집 서브 클라이언트를 허용하지만 대신 모든 단일 socketio 연결에 새로운 2 개 레디 스 연결을 요구하는 플러그인 노드를 작성 끝났다.

    나는 그것을 위해 사용을 찾을 수 밖에 일반적으로 생각 된 사람에서 작동합니다 많은 술집 서브 클라이언트를 허용하지만 대신 모든 단일 socketio 연결에 새로운 2 개 레디 스 연결을 요구하는 플러그인 노드를 작성 끝났다.

    이 코드는 기본적으로이 예에서 socket.io 클라이언트의 수를 연결하여 항상 여전히 2 개 레디 스 연결을 사용하지만, 모든 클라이언트가 자신의 채널에 가입 할 수 있습니다, socket.io 실행 및 설정을 가정한다. 이 예에서 모든 클라이언트는 메시지 '달콤한 메시지를!'가져 10 초 후에.

    socket.io 예는 (레디 스 이용하는 바-SUB)

    var
        RPubSubFactory = require('rpss.js');
    
    var 
        redOne = redis.createClient(port, host),
        redTwo = redis.createClient(port, host);
    
    var pSCFactory = new RPubSubFactory(redOne);
    
    io.sockets.on('connection', function(socket){
        var cps = pSCFactory.createClient();
        cps.onMessage(function(channel, message){
            socket.emit('message', message);
        });
        io.sockets.on('disconnect', function(socket){
            // Dont actually need to unsub, because end() will cleanup all subs, 
            // but if you need to sometime during the connection lifetime, you can.
            cps.unsubscribe('cool_channel');
            cps.end();
        });
        cps.subscribe('cool_channel')
    });
    
    setTimeout(function(){
        redTwo.publish('cool_channel', 'sweet message!');
    },10000);
    

    실제 플러그인 코드 :

    var RPubSubFactory = function(){
    
        var 
            len,indx,tarr;
        var
            dbcom = false,
            rPubSubIdCounter = 1,
            clientLookup = {},
            globalSubscriptions = {};
    
        // public
        this.createClient = function()
        {
            return new RPubSupClient();
        }
    
        // private
        var constructor = function(tdbcom)
        {
            dbcom = tdbcom;
            dbcom.on("message", incommingMessage);
        }
        var incommingMessage = function(rawchannel, strMessage)
        {
            len = globalSubscriptions[rawchannel].length;
            for(var i=0;i<len;i++){
                //console.log(globalSubscriptions[rawchannel][i]+' incomming on channel '+rawchannel);
                clientLookup[globalSubscriptions[rawchannel][i]]._incommingMessage(rawchannel, strMessage);
            }
        }
    
        // class
        var RPubSupClient = function()
        {
            var 
                id = -1,
                localSubscriptions = [];
    
            this.id = -1;
            this._incommingMessage = function(){};
    
            this.subscribe = function(channel)
            {
                //console.log('client '+id+' subscribing to '+channel);
                if(!(channel in globalSubscriptions)){
                    globalSubscriptions[channel] = [id];
                    dbcom.subscribe(channel);
                }
                else if(globalSubscriptions[channel].indexOf(id) == -1){
                    globalSubscriptions[channel].push(id);
                }
                if(localSubscriptions.indexOf(channel) == -1){
                    localSubscriptions.push(channel);
                }
            }
            this.unsubscribe = function(channel)
            {
                //console.log('client '+id+' unsubscribing to '+channel);
                if(channel in globalSubscriptions)
                {
                    indx = globalSubscriptions[channel].indexOf(id);
                    if(indx != -1){
                        globalSubscriptions[channel].splice(indx, 1);
                        if(globalSubscriptions[channel].length == 0){
                            delete globalSubscriptions[channel];
                            dbcom.unsubscribe(channel);
                        }
                    }
                }
                indx = localSubscriptions.indexOf(channel);
                if(indx != -1){
                    localSubscriptions.splice(indx, 1);
                }
            }
            this.onMessage = function(msgFn)
            {
                this._incommingMessage = msgFn;
            }
            this.end = function()
            {
                //console.log('end client id = '+id+' closing subscriptions='+localSubscriptions.join(','));
                tarr = localSubscriptions.slice(0);
                len = tarr.length;
                for(var i=0;i<len;i++){
                    this.unsubscribe(tarr[i]);
                }
                localSubscriptions = [];
                delete clientLookup[id];
            }        
            var constructor = function(){
                this.id = id = rPubSubIdCounter++;
                clientLookup[id] = this;
                //console.log('new client id = '+id);
            }        
            constructor.apply(this, arguments);
        }    
        constructor.apply(this, arguments);
    };
    
    module.exports = RPubSubFactory;
    

    나는 주변 청소 만하고 있지만, 일부 다른 속도 테스트를 수행 한 후, 나는 이것이 가장 빠른 내가 그것을 얻을 수이었다 결론을 내렸다 내가 할 수있는만큼 효율성을 개선하기 위해 노력했다.

    최신 버전의 경우 : https://github.com/Jezternz/node-redis-pubsub

  3. from https://stackoverflow.com/questions/14929700/what-should-i-be-using-socket-io-rooms-or-redis-pub-sub by cc-by-sa and MIT license