简体   繁体   English

当使用Express中间件时,可以组合套接字和Express吗?

[英]Combine sockets and express when using express middleware?

Is there a way to get the socket of a request inside of an express middleware? 有没有一种方法可以在快速中间件中获取请求的套接字?

ie: 即:

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!')
})

The idea being that express middleware has a req.socket property that references the connected socket from the same client. 表达中间件的想法是具有req.socket属性,该属性引用来自同一客户端的已连接套接字。 This would allow for some more complex use cases, such as: 这将允许一些更复杂的用例,例如:

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

The client would have an accurate progress bar of the image they just requested to create through the API. 客户端将具有他们刚刚通过API请求创建的图像的准确进度条。

Here's a way to connect socket.io and express. 这是连接socket.io和express的一种方法。 It uses express-session to create a secure session object for a given client. 它使用快速会话为给定的客户端创建安全的会话对象。 Then, when a socket.io connection happens, it gets the session for that client and stores the socket.id in the session. 然后,当发生socket.io连接时,它将获取该客户端的会话并将该socket.id存储在该会话中。

Then, you are positioned to either get the socketID from the session from within an express route handler so you can emit to that client over socket.io. 然后,您可以从快速路由处理程序中从会话中获取socketID,以便可以通过socket.io发送给该客户端。 Or, you can get session data from that user when you are in a socket.io message handler. 或者,当您处于socket.io消息处理程序中时,可以从该用户获取会话数据。 You can go either way. 您可以选择任何一种方式。 Here's the basic code: 这是基本代码:

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"});
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM