【问题标题】:Store Socket IO socket.id in Express session在 Express 会话中存储 Socket IO socket.id
【发布时间】:2021-03-17 09:05:42
【问题描述】:

我有一个使用 Angular 和 Express 的网络应用程序。我有一个用于数据库更新的 rest api,我还使用 SocketIO 来实时更新客户端。

我正在跟踪每个用户的活动套接字 ID 列表,但现在我想在我的快速路由中访问客户端套接字 ID,以便我可以向所有其他用户发送消息(相当于 socket.broadcast)

我正在尝试将套接字 ID 存储在表达式会话中,以便我可以在我的路由中访问它,但我无法让它工作。在下面的代码中,当套接字连接时,我正在记录我的会话,这显示了我添加的 socketio 密钥,但在 /jobs 请求中,socketio 密钥未定义..

我的 server.ts 是这样的:

import * as expsession from 'express-session'

// create Express app variable
const app = express()
// create HTTP server
const server = http.createServer(app);

// set up CORS so it can work Angular application at another domain/port
app.use(cors({
  origin: [ "http://localhost:4200" ], 
  credentials: true
}))

// install session middleware
const session = expsession({
  secret: 'random secret',
  saveUninitialized: true,
  resave: true,
  cookie: { secure: false }
});

// run session middleware for regular http connections
app.use(session);

// *** SOCKET IO *** //
const io = require('socket.io')(server);

// run session middleware for socket.io connections
io.use((socket, next) => {
  session(socket.request, socket.request.res || {}, next);
});

// when a socket.io connection connects, put the socket.id into the session
// so it can be accessed from other http requests from that client    
io.on('connection', (socket) => {
    console.log(`socket.io connected: ${socket.id}`);

    // save socket.io socket in the session
    socket.request.session.socketio = socket.id;
    socket.request.session.save();

    console.log("socket.io connection, session:\n", socket.request.session);
});

app.get('/jobs', (req, res) => {
  const session = req.session;
  console.log("JOBS: session at '/jobs':\n", session);

  Job.getJobs((err, jobs) => {
    if (err) {
      res.json({success: false, msg: err});
    } else {
      res.json(jobs);
    }
  });
});

我还在我的 Angular 服务请求中包含凭据,例如:

this.http.get(api_url + '/jobs', {withCredentials:true}).subscribe((jobs:IJob[]) => {
  this.jobs$.next(jobs)
})

【问题讨论】:

  • 您可以简单地完成app.set('io', io) 并像io = req.app.get('io') 一样使用
  • 但是如何在我的快速路由中获取客户端的套接字 ID?
  • 假设您的身份验证用户,您在 socket.io 连接中传递令牌/cookie,然后在连接时,您验证并将 id/用户分配给套接字,然后您可以执行循环通过连接为访问快速端点的当前用户获取正确的套接字
  • 如果每个用户有多个套接字连接怎么办? (例如多个标签)

标签: express session socket.io


【解决方案1】:

当一个套接字被连接时,一个 id 被创建(socket.id)并且默认情况下它加入一个具有该 id 的房间。如果您已经拥有客户端的 ID,只需将其发送到服务器并使用客户端 ID 加入房间。

socket.leave(socket.id);//leaving default room
socket.join(my_custom_id);//joining to custom id room

自定义 id 将作为 websocket7 id 出现在客户端。 如果您仍然不知道如何在您的快速路线中获取 id;使用带有 id 的 jsonwebtoken 并在您的路线中解码,就是这样。

例子:

var bearer = req.headers.authorization.split(" ")[1];//this is node, get headers with express way
var auth_data = jwt.decodeToken( bearer );

解码:

var jwt = require('jsonwebtoken');
var secret = 'your_secret';

function decodeToken(token){

    try {

        var decoded = jwt.verify( token , secret );
        return decoded;
    
    } catch (error) {
        console.log('jwt', error);
        return null;
    }

}

编码:

//data is an object with data you want to encode, id, etc
function createJsonWebToken(data){
    var token = jwt.sign( data, secret );
    return token
}

/*after encoding you send this token to the
client, then you send it back to the server
to the routes you need the data, then just
decoded it in that route*/

【讨论】:

  • 你能显示一些简单的代码来获取我的快速路线中的 id 吗?我已经尝试了很多年,但不知道该怎么做......
  • 我加了一个例子
猜你喜欢
  • 2013-10-20
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多