2012-11-23 34 views
2

我试图将Express(3.x)与NowJS(主要是围绕Socket.io的包装)结合起来创建一个实时应用程序,首先要求您记录我承认Node是新手,但是我对每个软件包的工作方式都有很好的掌握。但是,从NowJS访问快速会话信息会让我觉得合适。通过XHR轮询的Socket.io未通过Cookie

问题似乎是因为我被迫使用XHR-Polling(使用Heroku作为主机平台),我无法轻松访问Socket.io身份验证方法中的cookie信息。在authFunction的以下代码中,“data.headers.cookie”未定义。以迂回的方式(在Now.js代码中),这会在nowjs.on(“connect”,...)回调中留下“this.user.cookie”为空(但不是未定义)。这反过来让我无法获取会话信息。

从阅读来看,似乎只有使用websocket才可以使用cookie。没有cookie,我不知道哪个用户正在调用服务器,除了为它们生成的随机标识符。

任何人都可以提出如何解决这个问题吗?在建立与Now.js服务器的连接后,是否需要手动从客户端发送cookie?

var app = express(); 

app.configure(function(){ 
    app.set('port', process.env.PORT || 3000); 
    app.set('views', __dirname + '/views'); 
    app.engine('html', consolidate.swig); 
    app.set('view engine', 'html'); 

    app.use(express.favicon()); 
    app.use(express.logger('dev')); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieParser()); 
    app.use(express.session({ secret: "secrethere" , store: sessionStore})); 

    app.use(express.static(path.join(__dirname, 'public'))); 
    app.use(app.router); 
}); 

app.configure('development', function(){ 
    app.use(express.errorHandler({dumpExceptions: true, showStack: true})); 
}); 

//Map the routes 
var routes = require('./routes/routes')(db); 
app.get[...] //routes defined here 

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

var parseCookie = require('express/node_modules/connect').utils.parseCookie; 
var authFunction = function (data, accept) { 
// check if there's a cookie header 
if (data.headers.cookie) { 
    // if there is, parse the cookie 
    data.cookie = parseCookie(data.headers.cookie); 

    // note that you will need to use the same key to grad the 
    // session id, as you specified in the Express setup. 
    data.sessionID = data.cookie['connect.sid']; 
} else { 
    // if there isn't, turn down the connection with a message 
    // and leave the function. 
    return accept('No cookie transmitted.', false); 
} 

// accept the incoming connection 
accept(null, true); 
}; 

var everyone = nowjs.initialize(server, {socketio: {transports: ['xhr-polling', 'jsonp-polling'], authorization: authFunction}}); 

nowjs.on('connect', function (socket) { 
//TODO - This will need to be based on the URL that is being visited, or 
//similar to establish that users are viewing the same thing 
var sid = unescape(this.user.cookie["connect.sid"]); //# you DO have to unescape the session id! 

sessionStore.get(sid, function(err, sess){ 
    console.log("That group who joined? his userId is " + sess.userId) 
}); 

var newRoom = "group";//this.user.session;//.groupName; 
var newGroup = nowjs.getGroup(newRoom); 
this.now.serverRoom = newRoom; 
newGroup.addUser(this.user.clientId); 
}); 

编辑:当然,我宁愿喜欢这里最多的回答简单的解决方案:Session support in Now.js,但是,这并不为我工作了(可能)同样的原因 - 我的“cookie”是空的,不包含“connect.sid”键。

回答

0

经过大量尝试不同的事情之后,我意识到这实际上与我使用的环境(Cloud9 IDE)有关。

使用Cloud9进行调试时,它们会为您提供一个很好的网址,以便在“http:// [projectname]。[username] .c9.io”中浏览您的网站。但是,NowJS将其请求发送到“http:// project- [unique ID] .rhcloud.com/socket.io/1/xhr-polling/...”。这是而不是提示cookie与请求一起发送,因为它不是与cookie关联的主机(好的,术语可能稍微偏离此处)。

要解决此问题,我使用“http:// project- [unique ID] .rhcloud.com/...”作为我的调试基础,并且它似乎正常工作100%。 Heroku似乎没有这个问题,因为所有请求(常规页面请求 socketio)都通过相同的主机。