2013-03-02 7 views
9

तो मैं सत्र को अपने सॉकेट के अंदर काम करने की कोशिश कर रहा हूं। ('कनेक्शन', ...) मैं हाल के संस्करणों का उपयोग करके यह काम करने की कोशिश कर रहा हूं: सॉकेट.ओ - 0.9.13, एक्सप्रेस - 3.1.0 और अन्य मॉड्यूल के नवीनतम संस्करण।मैं redis, express और socket.io का उपयोग करके काम करने के लिए सत्र कैसे प्राप्त कर सकता हूं?

वैसे भी मैंने मॉड्यूल 'connect-redis' और 'session.socket.io' दोनों का उपयोग करने का प्रयास किया है और दोनों में समान समस्याएं हैं।

मेरे कोड में मेरे पास 2 रेडिस स्टोर्स हैं (सॉकेटियो। रेडिसस्टोर और आवश्यकता है ('कनेक्ट-रेडिस') (एक्सप्रेस)), अब यह प्रोग्राम ठीक चल रहा है, लेकिन एक्सप्रेस और सॉकेट.ओओ को सत्र डेटा साझा करने की आवश्यकता है, मैं सोच रहा था कि क्या यह सेटअप सत्रों का सही ढंग से उपयोग करेगा? सत्र स्टोर को व्यक्त/सॉकेटियो के लिए एक ही वस्तु होने की आवश्यकता है? मेरे लिए एक ग्रे क्षेत्र का थोड़ा सा, क्योंकि 2 RedisStore पृष्ठभूमि में एक ही डीबी का उपयोग करेगा?

मैंने दोनों जगहों पर सॉकेट.ओ रेडिसस्टोर या कनेक्ट-रेडिस रेडिसस्टोर का उपयोग करने का प्रयास किया है, लेकिन socket.io कनेक्ट-रेडिस रेडिसस्टोर पसंद नहीं करता है और एक्सप्रेस socketio.redisStore की तरह नहीं है।

अगर मैं कनेक्ट-redis RedisStore तो socket.io/lib/manager.js शिकायत का उपयोग करें: this.store.subscribe (... लेखन त्रुटि ऑब्जेक्ट # में कोई विधि 'सदस्यता लें'

है अगर मैं का उपयोग socketio.RedisStore तो व्यक्त/node_modules/कनेक्ट/lib/मिडलवेयर/session.js शिकायत: लेखन त्रुटि: ऑब्जेक्ट # में कोई विधि 'प्राप्त'

है * ध्यान दें मैं नहीं बल्कि session.socket.io प्लगइन काम कर रहे मिलेगा, लेकिन जब मैं उस प्लगइन के साथ एक ही सेटअप करता हूं, एक्सप्रेस (भी) शिकायत करता है: टाइप एरर: ऑब्जेक्ट # में कोई तरीका नहीं है 'प्राप्त करें'

तो क्या यह ठीक है कि मैं सत्रों के लिए 2 अलग-अलग RedisStores का उपयोग करता हूं, या क्या मुझे किसी एक तरह से या दूसरे के लिए काम करने की आवश्यकता है, और यदि ऐसा है तो कैसे ठीक किया जाए?

मेरे वर्तमान कोड इस तरह दिखता है:

var 
    CONST = { 
     port: 80, 
     sessionKey: 'your secret sauce' 
    }; 

var 
    redis = require('redis'); 

var 
    express = require('express'), 
    socketio = require('socket.io'), 
    RedisStore = require('connect-redis')(express); 

var 
    redisStore = new RedisStore(), 
    socketStore = new socketio.RedisStore(); 

var 
    app = express(), 
    server = require('http').createServer(app), 
    io = socketio.listen(server); 

app.configure(function(){ 
    app.use(express.cookieParser(CONST.sessionKey)); 
    app.use(express.session({ secret: CONST.sessionKey, store: redisStore })); 
    app.use(express.static(__dirname + '/test')); 
    app.get('/', function (req, res) {res.sendfile(__dirname + '/test/' + 'index.htm');}); 
}); 

io.configure(function(){ 
    io.set('log level', 1); 
    io.enable('browser client minification'); 
    io.enable('browser client etag'); 
    io.enable('browser client gzip'); 
    io.set('store', socketStore); 
}); 

io.sockets.on('connection', function(socket){ 
    socket.emit('message', 'Test 1 from server') 
}); 

server.listen(CONST.port); 

console.log('running...'); 

उत्तर

4
io.configure अंदर

, आप http सत्र के साथ सॉकेट से जोड़ने के लिए की है।

यहां कोड का एक टुकड़ा है जो कुकी को निकालता है (यह xhr-polling के साथ सॉकेट.io का उपयोग कर रहा है, मुझे नहीं पता कि यह वेबसाईट के लिए काम करेगा, हालांकि मुझे संदेह है कि यह काम करेगा)। ,

socket.on("selector", function(data, reply) { 
    var session = this.handshake.session; 
    ... 
} 

यह भी है अतिरिक्त लाभ यह जाँच करता है कि एक वैध सत्र है उन में तो केवल अपने प्रवेश किए सॉकेट का उपयोग कर सकते हैं:

var cookie = require('cookie'); 
var connect = require('connect'); 

var sessionStore = new RedisStore({ 
    client: redis // the redis client 
}); 

socketio.set('authorization', function(data, cb) { 
    if (data.headers.cookie) { 
    var sessionCookie = cookie.parse(data.headers.cookie); 
    var sessionID = connect.utils.parseSignedCookie(sessionCookie['connect.sid'], secret); 
    sessionStore.get(sessionID, function(err, session) { 
     if (err || !session) { 
     cb('Error', false); 
     } else { 
     data.session = session; 
     data.sessionID = sessionID; 
     cb(null, true); 
     } 
    }); 
    } else { 
    cb('No cookie', false); 
    } 
}); 

तो आप उपयोग कर सत्र पहुँच सकते हैं। हालांकि, आप एक अलग तर्क का उपयोग कर सकते हैं।

+0

त्वरित उत्तर के लिए धन्यवाद, तो यह है अगर मैं session.socket.io प्लगइन का उपयोग करना चाहता हूं तो वही समाधान? या यह एक अलग समस्या है? –

+0

यह session.socket.io प्लगइन का उपयोग नहीं करता है और socket.io और एक्सप्रेस के हाल के संस्करणों पर काम करता है। –

+0

आह ठीक है, मैं इसे जाने के लिए धन्यवाद दे सकता हूं। –

4

अपने अंतिम टिप्पणी को देखते हुए मैं एक ही समस्या थी और एक समाधान पाया (redis का उपयोग कर कई प्रक्रियाओं पर अपने राज्य को साझा करने में सक्षम नहीं होगा):

var express = require("express.io"); 
var swig = require('swig'); 
var redis = require('redis'); 
var RedisStore = require('connect-redis')(express); 

workers = function() { 
    var app = express().http().io(); 

    app.use(express.cookieParser()); 
    app.use(express.session({ 
     secret: 'very cool secretcode', 
     store: new RedisStore({ client: redis.createClient() }) 
    })); 

    app.io.set('store', new express.io.RedisStore({ 
     redisPub: redis.createClient(), 
     redisSub: redis.createClient(), 
     redisClient: redis.createClient() 
    })); 


    app.get('/', function(req, res) { 
     res.render('index'); 
    }); 

    app.listen(3000); 


    app.io.route('ready', function(req){ 
     //setup session stuff, use session stuff, etc. Or make new routes 
    }); 
}; 

cluster = require('cluster'); 
numCPUs = require('os').cpus().length; 

if (cluster.isMaster) 
{ 
    for (var i = 0; i < numCPUs; i++) 
    { 
     cluster.fork(); 
    } 
} 
else 
{ 
    workers(); 
} 
+0

यहां कुंजी 'app.io.set है ('स्टोर', नया express.io.RedisStore ({'express.io.RedisStore का उपयोग कर। धन्यवाद! – ruffrey

संबंधित मुद्दे

 संबंधित मुद्दे