2012-04-28 75 views
14

我在Node中使用Express框架和會話中間件的典型Web應用程序。我也爲我的應用程序的某些動態部分使用Socket.io(目前,這是一種聊天機制,但這是切線)。我已經能夠自己成功設置會話和socket.io,但希望將它們組合起來(EG:將套接字聊天消息與用戶帳戶相關聯,而不會觸及數據庫)。無法從支持Socket.IO的cookie中獲取Express會話ID

需要注意的是(我可以看到這是一個可能的問題點),我在不同的端口上運行兩個快速服務器:一個用於常規HTTP通信,另一個用於HTTPS通信。但是,我使兩臺服務器都進行了理想的配置並共享相同的會話存儲。會話確實在http和https頁面之間持續存在。會話最初是通過HTTPS提供的頁面設置的,而socket.io頁面是vanilla HTTP。

我按照指南here來實現我正在尋找的有關集成socket.io和會話。但是,在授權函數中,儘管我的應用程序的基於會話的部分按預期工作,但data.headers.cookie從未設置。更奇怪的是,在設置會話後,如果我在瀏覽器中執行console.log(document.cookie),我會得到一個空字符串,但是當我使用Firefox開發人員工具欄查看cookie時,快捷和連接都會有一個SID cookie。

這裏是服務器代碼的相關部分:

var config = { 
    ip   : "127.0.0.1", 
    httpPort : 2031, 
    httpsPort : 2032 
}; 

var utils  = require("./utils"), 
    express  = require('express'), 
    fs   = require('fs'), 
    parseCookie = require('./node_modules/express/node_modules/connect').utils.parseCookie, 
    routes  = require('./routes')(config); 

var httpsOpts = { 
    key : fs.readFileSync("cert/server-key.pem").toString(), 
    cert: fs.readFileSync("cert/server-cert.pem").toString() 
}; 

var app    = express.createServer(), 
    https   = express.createServer(httpsOpts), 
    io    = require("socket.io").listen(app, { log: false}), 
    helpers   = require("./helpers.js"), 
    session   = new express.session.MemoryStore(), 
    sessionConfig = express.session({ 
     store : session, 
     secret : 'secret', 
     key  : 'express.sid', 
     cookie : {maxAge : 60 * 60 * 1000} 
    }); //share this across http and https 

configServer(app); 
configServer(https); 

//get SID for using sessions with sockets 
io.set('authorization', function(data, accept){ 
    if(data.headers.cookie){ 
     data.cookie = parseCookie(data.headers.cookie); 
     data.sessionID = data.cookie['express.sid']; 
    } else { 
     return accept("No cookie transmitted", false); 
    } 

    accept(null, true); 
}); 

io.sockets.on('connection', function(socket){ 
    //pull out session information in here 
}); 

function configServer(server) { 
    server.configure(function(){ 
     server.dynamicHelpers(helpers.dynamicHelpers); 
     server.helpers(helpers.staticHelpers); 
     server.set('view options', { layout: false }); 
     server.set('view engine', 'mustache'); 
     server.set('views', __dirname + '/views'); 
     server.register(".mustache", require('stache')); 
     server.use(express.static(__dirname + '/public')); 
     server.use(express.bodyParser()); 
     server.use(express.cookieParser()); 
     server.use(sessionConfig); 
    }); 
} 

而這裏的客戶端上的相關代碼:

<script src="/socket.io/socket.io.js"></script> 
<script type="text/javascript"> 
    $(document).ready(function(){ 
     var socket = io.connect('http://127.0.0.1'); //make sure this isn't localhost! 
     socket.on('server', function(data){ 
      //socket logic is here 
     }); 
    } 
</script> 

UPDATE

即使手動設置cookie後(而不僅僅是一個會話變量)在使用SocketIO的頁面的路由中,請求的Cookie部分仍然存在缺席。

回答

11

我從來沒有想到這件事,直到告訴看到客戶端的初始化。我將地址從localhost更改爲顯式IP(127.0.0.1),並且現在正在使用Socket.IO中的標頭髮送cookie。我不確定這是否顯而易見,因爲我認爲本地主機映射到127.0.0.1無論如何。

+8

正是!這就是我需要客戶端代碼的原因。你也可以使用'var socket = io.connect();'而不需要提供主機。應該管用。 – freakish 2012-04-28 16:53:49

+0

對我來說確切的問題,這完美的工作。 – bento 2012-07-28 17:21:03