var express = require('express'),
session = require('express-session'),
RedisStore = require('connect-redis')(session),
sessionStore = new RedisStore(),
io = require('socket.io').listen(server);
var sessionMiddleware = session({
store : sessionStore,
secret : "blabla",
cookie : { ... }
});
function socketAuthentication(socket, next) {
var sessionID = socket.request.sessionID;
sessionStore.get(sessionID, function(err, session) {
if(err) { return next(err); }
if(typeof session === "undefined") {
return next( new Error('Session cannot be found') );
}
console.log('Socket authenticated successfully');
next();
});
}
io.of('/abc').use(socketAuthentication).on('connection', function(socket) {
// setup events and stuff
});
io.use(function(socket, next) {
sessionMiddleware(socket.request, socket.request.res, next);
});
app.use(sessionMiddleware);
app.get('/', function(req, res) { res.render('index'); });
server.listen(8080);
index.html
<body>
...
<script src="socket.io/socket.io.js"></script>
<script>
var socket = io('http://localhost:8080/abc');
</script>
</body>
所以,客户端的io('http://localhost:8080/abc');
将发送初始HTTP握手请求到服务器,服务器可以通过它获取cookie和许多其他请求信息。因此,服务器可以通过socket.request访问该初始请求。
我的第一个问题是为什么握手请求不在express-session中间件的范围内?(更普遍地说,在app.use
中间件的范围内?)某种程度上,我期望这个app.use(sessionMiddleware);
会在初始请求之前触发,然后轻松访问socket.request.session
其次,定义了io.use()
中间件将触发哪些场景?仅用于初始的HTTP握手请求吗?看起来像io.use()
用于与socket相关的东西(问题是:什么东西),而app.use
用于标准请求。
我不太确定为什么在上面的例子中io.use()
会在io.of('/abc').use()
之前触发。有意我将io.of('/abc').use()
放在前面来测试是否可以正常工作,结果它确实可以正常工作。应该写反了。
最后,像一些人在链接的问题中指出的那样,socket.request.res有时会是undefined
,导致应用程序崩溃,可以通过提供空对象而不是socket.request.res来解决这个问题,比如:sessionMiddleware(socket.request, {}, next);
,这对我来说看起来像一个肮脏的技巧。为什么socket.request.res会产生undefined
的原因是什么?