使用express中间件时要结合socket和express吗?

问题描述 投票:0回答:2

有没有办法在快速中间件内获取请求的套接字?

即:

import express from 'express';
import io from 'socket.io';

const app = express();

// combine app and io somehow ...

// When client makes a GET request to '/emit/to/self', that client's socket will recieve the 'hello:world' message.
app.get('/emit/to/self', (req, res) => {
  req.socket.emit('hello:world', { ... });
  res.send('You just triggered your own socket!')
})

这个想法是,快速中间件有一个

req.socket
属性,它引用来自同一客户端的已连接套接字。这将允许一些更复杂的用例,例如:

app.post('/image/create', (req, res) => {
  createExpensiveImage({
    onProgress: (progress) => { req.socket.emit('image:progress', { progress }) },
  });
})

客户将拥有他们刚刚通过 API 请求创建的图像的准确进度条。

javascript node.js sockets express socket.io
2个回答
9
投票

这里介绍一种连接socket.io和express的方法。它使用 Express-Session 为给定客户端创建安全会话对象。然后,当发生 socket.io 连接时,它会获取该客户端的会话并将 socket.id 存储在会话中。

然后,您可以从快速路由处理程序中的会话中获取套接字ID,以便您可以通过socket.io 向该客户端发送。或者,当您位于 socket.io 消息处理程序中时,您可以从该用户获取会话数据。你可以选择任何一种方式。这是基本代码:

const express = require('express');
const app = express();
const server = app.listen(80);
const io = require('socket.io')(server);
const expsession = require('express-session');
const path = require('path');

// initialize session middleware
const sessionMiddleware = expsession({
  secret: 'random secret',
  saveUninitialized: true,
  resave: true
});

// hook up session for express routes
app.use(sessionMiddleware);

// hook up the session for socket.io connections
io.use(function(socket, next) {
    sessionMiddleware(socket.request, socket.request.res, next);
});

// when a socket.io connect connects, get the session and store the id in it
io.on('connection', function(socket) {
    // socket.handshake.headers
    console.log(`socket.io connected: ${socket.id}`);
    // save socket.io socket in the session
    console.log("session at socket.io connection:\n", socket.request.session);
    socket.request.session.socketio = socket.id;
    socket.request.session.save();
});

// general middleware to demo an increasing, per-client value in the session
app.use(function(req, res, next) {
    // req.session
    const session = req.session;
    if (!session.cntr) session.cntr = 0;
    ++session.cntr;
    next();
});

// route handler to serve up default page    
app.get("/", function(req, res) {
    const session = req.session;
    console.log("\n\npage load\n---------------------------\n");
    console.log("session:\n", session);
    res.sendFile(path.join(__dirname, "socket-io-session.html"));
});

let cntr = 1;

// test route to show using socket.io .emit() from an express route
app.get("/api/test", function(req, res) {
    const session = req.session;
    io.sockets.connected[session.socketio].emit('show', cntr++);
    res.json({greeting: "hello"});
});

0
投票

最后,套接字版本 4.6.0 可以实现

这里是基本示例:

import session from "express-session";

io.engine.use(session({
  secret: "keyboard cat",
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}));

Socket.io 官方文档:https://socket.io/docs/v4/middlewares/#compatibility-with-express-middleware

© www.soinside.com 2019 - 2024. All rights reserved.