我想在用户进入应用程序时创建一个用户会话.并在需要时阅读课文.这是我的try

var io   = require('socket.io'),
    express = require('express');
    querystring = require('querystring');

var app = express.createServer();
app.get('/', function(req, res){
    var sessionVal = querystring.parse(req.url.substr(2));// sessionVal is an email for example: me@gmail.com
    app.use(express.cookieParser());
    app.use(express.session({ secret: sessionVal }));
});
var socket = io.listen(app);
socket.on('connection', function(client) {
    client.on('message', function(message) {
        // message will be an object {text:'user text chat blah blah', email:'me@gmail.com'}
        // if the seesion stored, has the same value with message.email
        // then the message will be broadcasted
            socket.broadcast(message.text);
        // else will not broadcast  
    });
});

app.listen(4000);

推荐答案

我需要在这里指出,您错误地将中间件添加到应用程序中.app.use个调用不应在app.get请求处理程序内完成,而应在其外部完成.只需在createServer之后直接给他们打电话,或者看看the other examples in the docs.

传递给express.session的秘密应该是一个字符串常量,或者是从配置文件中获取的内容.不要给它提供客户可能知道的东西,这实际上很危险.这是一个只有服务器应该知道的秘密.

如果您想在会话中存储邮箱地址,只需执行以下操作:

req.session.email = req.param('email');

有了这条路...


如果我理解正确,您要做的是处理一个或多个HTTP请求并跟踪会话,然后稍后打开一个套接字.IO连接,您也需要从中获取会话数据.

这个问题的棘手之处在于插座.木卫一让魔法在任何http.Server上发挥作用的方法是劫持request事件.因此,永远不会在套接字上调用Express(或者说Connect)会话中间件.IO连接.

不过,我相信你可以通过一些技巧来实现这一点.

您可以访问Connect的会话数据;您只需要获取会话存储的引用.最简单的方法是在拨打express.session之前自己创建店铺:

// A MemoryStore is the default, but you probably want something
// more robust for production use.
var store = new express.session.MemoryStore;
app.use(express.session({ secret: 'whatever', store: store }));

每个会话存储都有一个get(sid, callback)方法.sid参数或会话ID存储在客户端的cookie中.该cookie的默认名称为connect.sid.(但您可以通过在express.session通话中指定key选项为其命名.)

然后,您需要访问套接字上的cookie.IO连接.不幸的是,插座.IO似乎不允许你访问http.ServerRequest.一个简单的解决方法是在浏览器中获取cookie,然后通过套接字发送.IO连接.

服务器上的代码将如下所示:

var io      = require('socket.io'),
    express = require('express');

var app    = express.createServer(),
    socket = io.listen(app),
    store  = new express.session.MemoryStore;
app.use(express.cookieParser());
app.use(express.session({ secret: 'something', store: store }));

app.get('/', function(req, res) {
  var old = req.session.email;
  req.session.email = req.param('email');

  res.header('Content-Type', 'text/plain');
  res.send("Email was '" + old + "', now is '" + req.session.email + "'.");
});

socket.on('connection', function(client) {
  // We declare that the first message contains the SID.
  // This is where we handle the first message.
  client.once('message', function(sid) {
    store.get(sid, function(err, session) {
      if (err || !session) {
        // Do some error handling, bail.
        return;
      }

      // Any messages following are your chat messages.
      client.on('message', function(message) {
        if (message.email === session.email) {
          socket.broadcast(message.text);
        }
      });
    });
  });
});

app.listen(4000);

这假设您只想读取现有会话.您实际上无法创建或删除会话,因为套接字.IO连接可能没有HTTP响应来发送Set-Cookie报头(想想WebSockets).

如果要编辑会话,可以使用某些会话存储.例如,CookieStore不起作用,因为它还需要发送一个Set-Cookie头,但它不能.但是对于其他store ,你可以try 调用set(sid, data, callback)方法,看看会发生什么.

Node.js相关问答推荐

node 无法验证第一个证书

monorepo内的NPM包使用不在注册表中的本地包

MongoDB-如何验证Document字段以仅允许特定的文件扩展名?

如何在JavaScript中使用Mongoose将项推送到MongoDB中的重嵌套数组

MongoDB的方面查询的Postgres类似功能

条件内的表达式

Sequelize、postgres和posgis:在n°;公里

为什么即使数据库确实更新了,此 POST 也无法解析并返回 200 代码?

如果我在 tsx 文件中使用了use client,ssr 会如何发生?

使用NodeJS通过服务账号列出Google Workspace用户

SvelteKit应用程序立即退出,没有错误

MongoDB - mongoose :如何查询这个? 填充()不起作用.它显示空

只要我在后端正确验证所有内容,就可以将这些数据存储在本地存储中吗?

获取数组的至少一个元素包含子字符串的文档

我怎样才能让`git`失败而不是要求提供凭据

来自 Node-aws 的 Dynamo Local:所有操作都失败无法对不存在的表执行操作

如何使用 Puppeteer 从输入中删除现有文本?

Node.js 支持 =>(箭头函数)

webpack css-loader 在外部样式表的 url() 引用中找不到图像

我无法全局安装 nodemon,nodemon无法识别