使用express中间件时结合sockets和express?
Posted
技术标签:
【中文标题】使用express中间件时结合sockets和express?【英文标题】:Combine sockets and express when using express middleware? 【发布时间】:2017-07-11 19:42:43 【问题描述】:有没有办法在快速中间件中获取请求的套接字?
即:
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!')
)
这个想法是 express 中间件有一个 req.socket
属性,它引用来自同一客户端的连接套接字。这将允许一些更复杂的用例,例如:
app.post('/image/create', (req, res) =>
createExpensiveImage(
onProgress: (progress) => req.socket.emit('image:progress', progress ) ,
);
)
客户端将获得他们刚刚请求通过 API 创建的图像的准确进度条。
【问题讨论】:
也许这个How to share sessions between socket.io and express。仅供参考,当您在 Google 上搜索“share session express socket.io”时,会有数百次点击。很多关于这个的文章。 【参考方案1】:这里有一种连接socket.io和express的方法。它使用 express-session 为给定的客户端创建一个安全的会话对象。然后,当 socket.io 连接发生时,它会获取该客户端的会话并将 socket.id 存储在会话中。
然后,您可以从快速路由处理程序中的会话中获取 socketID,以便您可以通过 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");
);
【讨论】:
很好,谢谢。我以前见过 express 和 sockets 之间的会话共享,但从未想过以这种方式使用它。事后看来似乎很简单。 由于某些原因,req.session
没有适合我的 socketio。会话中只有一个cookie。以上是关于使用express中间件时结合sockets和express?的主要内容,如果未能解决你的问题,请参考以下文章
如何结合 Express.JS 使用 Socket.io(使用 Express 应用程序生成器)
使用 Express.js v4 和 Socket.io v1 的会话
如何在用户从帐户注销时断开事件触发(node.js + express socket.io)