【问题标题】:Expressjs+socket.io+express-sessionExpressjs+socket.io+express-session
【发布时间】:2014-07-10 14:20:38
【问题描述】:

我的 server.js 中有这段代码。

var app = require('express')(),
        session = require('express-session'),
        cookie = require('cookie'),
        cookieParser = require('cookie-parser'),
        manager = require('./sockets/manager');

var sessionStore = new session.MemoryStore();


app.use(cookieParser('secret'));
app.use(session({
    name: 'sid',
    store: sessionStore,
    secret: 'secret',
    saveUninitialized: true,
    resave: true,
    cookie: {
        path: '/',
        httpOnly: true,
        secure: false,
        maxAge: null
    }
}));

var server = require('http').Server(app).listen(8888),
    io = require('socket.io')(server);

io.use(function(socket, next) {
    var data= socket.request;

    if (data.headers.cookie) {
        data.cookie = cookie.parse(cookieParser.signedCookie(data.headers.cookie, 'secret'));

        console.log('data.cookies ( %s )', JSON.stringify(data.cookie)); 
        // print 'io=id_place', cookies doesn't have sid, why?

        if (data.cookie.sid) {
            data.sid = request.cookie.sid;
            sessionStore.get(request.cookie.sid, function(err, session) {
                request.session = session;
            });
        }
    }

    next();
});

manager.use(io);

控制台日志向我显示了这个 cookie request.cookies ( {"io":"lHKSseNH5UrnJisSAAAA"} )。 我刚刚看到了很多 expressjs 3 和 socket 0.9 的例子,但是我有:

"socket.io": "^1.0.6", “快递”:“~4.5.1”, “快速会话”:“~1.6.4”

它不起作用。

我有什么错误吗?

【问题讨论】:

    标签: node.js express socket.io-1.0


    【解决方案1】:

    我已经为您创建了解决方案:enter link description here。如您所见,套接字对象具有握手属性,其中包括带有 cookie 的请求标头。

    【讨论】:

    • 在使用 connect-mongo 在 mongodb 中存储会话时如何使用您的代码。请指导我我找不到任何解决方案
    【解决方案2】:

    下面的链接有一个非常简单的解决方案,可以在 Express 和 Socket.IO 之间共享会话。

    Simple Answer

    Express 4.x 的中间件 API 非常接近 Socket.IO 1.x,我们可以为两者使用相同的会话中间件。

    那里的示例使用 MongoDB 会话存储。我尝试使用 express-session 的默认会话存储并且它有效。

    io.js

    var io = require('socket.io')();
    
    io.on('connection', function (socket) {
        console.log(socket.request.session);
        console.log('New client connected!');
    });
    
    module.exports = io;
    

    app.js

    var express = require('express'),
        path = require('path'),
        favicon = require('serve-favicon'),
        logger = require('morgan'),
        cookieParser = require('cookie-parser'),
        bodyParser = require('body-parser'),
        expressSession = require('express-session'),
        io = require('./io'),
    
        index = require('./routes/index'),
    
        app = express(),
    
        mongoose = require('mongoose'),
        uri = 'localhost:27017/selfie_showcase',
        options = {
            db: { native_parser: true },
            server: { socketOptions: { keepAlive: 1 } },
            replset: { socketOptions: { keepAlive: 1 } },
            user: 'arun',
            pass: 'arun'
        },
    
        sessionMiddleware = expressSession({
            secret: 'my_s3cr3t_s3ss1on',
            resave: true,
            saveUninitialized: true
        });
    
    
    // connect to MongoDB
    mongoose.connect(uri, options, function(err) {
        if(err) {
            console.log(err);
        }
    });
    
    // configure socket.io to share session with express
    io.use(function(socket, next) {
        sessionMiddleware(socket.request, {}, next);
    });
    
    // view engine setup
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'ejs');
    
    // uncomment after placing your favicon in /public
    //app.use(favicon(__dirname + '/public/favicon.ico'));
    app.use(sessionMiddleware);
    app.use(logger('dev'));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    app.use('/', index);
    
    // catch 404 and forward to error handler
    app.use(function(req, res, next) {
        var err = new Error('Not Found');
        err.status = 404;
        next(err);
    });
    
    // error handlers
    
    // development error handler
    // will print stacktrace
    if (app.get('env') === 'development') {
        app.use(function(err, req, res, next) {
            res.status(err.status || 500);
            res.render('error', {
                title: 'Error',
                message: err.message,
                error: err
            });
        });
    }
    
    // production error handler
    // no stacktraces leaked to user
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            title: 'Error',
            message: err.message,
            error: {}
        });
    });
    
    
    module.exports = app;
    

    bin/www

    #!/usr/bin/env node
    
    /**
     * Module dependencies.
     */
    
    var app = require('../app');
    var io = require('../io');
    var debug = require('debug')('selfie-showcase:server');
    var http = require('http');
    
    /**
     * Get port from environment and store in Express.
     */
    
    var port = normalizePort(process.env.PORT || '3000');
    app.set('port', port);
    
    /**
     * Create HTTP server.
     */
    
    var server = http.createServer(app);
    io.attach(server);
    
    /**
     * Listen on provided port, on all network interfaces.
     */
    
    server.listen(port);
    server.on('error', onError);
    server.on('listening', onListening);
    
    /**
     * Normalize a port into a number, string, or false.
     */
    
    function normalizePort(val) {
      var port = parseInt(val, 10);
    
      if (isNaN(port)) {
        // named pipe
        return val;
      }
    
      if (port >= 0) {
        // port number
        return port;
      }
    
      return false;
    }
    
    /**
     * Event listener for HTTP server "error" event.
     */
    
    function onError(error) {
      if (error.syscall !== 'listen') {
        throw error;
      }
    
      var bind = typeof port === 'string'
        ? 'Pipe ' + port
        : 'Port ' + port
    
      // handle specific listen errors with friendly messages
      switch (error.code) {
        case 'EACCES':
          console.error(bind + ' requires elevated privileges');
          process.exit(1);
          break;
        case 'EADDRINUSE':
          console.error(bind + ' is already in use');
          process.exit(1);
          break;
        default:
          throw error;
      }
    }
    
    /**
     * Event listener for HTTP server "listening" event.
     */
    
    function onListening() {
      var addr = server.address();
      var bind = typeof addr === 'string'
        ? 'pipe ' + addr
        : 'port ' + addr.port;
      debug('Listening on ' + bind);
    }
    

    希望这可能对任何未来的用户有所帮助。

    P.S:我使用了express-generator,所以这种模块拆分。

    【讨论】:

      【解决方案3】:

      试试这个模块express-socket.io-session

      它允许您在 express 和 socket.io(反之亦然)之间共享基于 cookie 的 session 数据。

      您可以使用任何您想要的会话数据存储,因为您以常规方式创建快速会话对象,然后与 socket.io 共享它。

      它适用于 express >4.0 和 socket.io >1.0

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-07
        • 2017-10-16
        • 1970-01-01
        • 2017-04-10
        • 2015-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多