我的程序中的套接字有问题。导出“io”连接,虽然我可以从正常程序的任何部分进行广播(仅通过引用“io”),但我不能使用“socket”并与其进行广播,除非它与“io”处于同一连接内。我想知道如何从程序的任何其他部分使用套接字,使用诸如“socket.emit ()”或“socket.broadcast.emit”等函数。或者如何调用这个函数。
这是我的 index.js:
const express = require('express');
const restApi = express();
const cors = require('cors');
const server = require('http').createServer(restApi);
const rutas = require('./src/routes/Routes.js');
const io = require('./src/socket/SocketManager.js');
io.attach(server);
restApi.use(express.json());
restApi.use(express.static('public'));
restApi.use(cors());
restApi.options('*', cors());
server.listen(4040, () => console.log('Listening server in port 4040'));
restApi.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
restApi.use('/api',rutas);
我的 managersocket.js:
const io = require('socket.io')();
io.on('connection', function (socket) {
console.log('NUEVA CONEXION: ',socket.id);
socket.emit('recoger',socket.id);
});
module.exports = io;
这是我想使用套接字或至少调用函数的地方。
和 User.js:
var io = require('../../socket/SocketManager');
var RouterUser = function(){
this.practicafuncion = function (req,res){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
console.log('probando entrar por rest y que salga un mensaje por socket');
res.send({
status:'Aprobado',
msj:'Enviado por rest'
});
//this works correctly. io.sockets.emit('mensaje','**MENSAJESERVIDORPORSOCKET**');
//This is not the problem when using "socket". socket.broadcast.emit('mensaje','**MENSAJESERVIDORPORSOCKET**');
};
}
module.exports = function(){
var instancia = new RouterUser();
return instancia;
};
同样是整个代码所在的仓库
https://github.com/proxirv/Socket.io-router
最佳答案
socket
是一个临时对象,仅在一个特定客户端连接期间存在。而且,它们可能有无数个(每个连接的客户端一个或多个)。因此,您不只是导出一个 socket
或将其塞入全局并尝试在任何地方使用它。
因此,如果您尝试做的是为刚刚收到 http 请求的用户访问 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');
// install session middleware
const sessionMiddleware = expsession({
secret: 'random secret',
saveUninitialized: true,
resave: true
});
// run session middleware for regular http connections
app.use(sessionMiddleware);
// run session middleware for socket.io connections
io.use(function(socket, next) {
sessionMiddleware(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', 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();
});
// any arbitrary express route definition
// Note: you can't send socket.io data in a request that loads an HTML page
// because that client hasn't yet established the socket.io connection
// for that page. The socket.io connections will be created after
// the browser loads this 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"));
});
// Upon an API call from a page that already has a socket.io connection,
// respond to the API call and send something to that page's socket.io socket
app.get("/api/test", function(req, res) {
const session = req.session;
io.sockets.connected[session.socketio].emit('show', "sending some data");
console.log("session:\n", session);
console.log("session.socketio:\n", session.socketio);
res.json({greeting: "hello"});
});
以下是该概念中的步骤:
- 为常规 HTTP 连接设置快速 session 。这为您提供了一个存储属于某个特定客户的东西的地方(由 cookie 键入)
- 为 socket.io 连接设置快速 session ,这样您也可以访问 socket.io 连接中的快速 session 数据。
- 当发生 socket.io 连接时,将 socket.id 存储在 session 中。这使得 socket.id 可用于来自该特定客户端的 future http 请求
- 当某个 future 的 http 请求来自该客户端时,您可以进入 session ,获取 socket.id 值(它只是一个字符串),然后使用它来获取该用户的套接字,一旦您拥有套接字,您可以使用
socket.emit()
仅向该用户发送数据。
如果你没有其他原因使用 express-session,你也可以在 socket.io 连接连接时将 socket.id 单独放入 cookie 中,然后在连接期间从 cookie 中获取 socket.id你的 http 请求。
关于javascript - 在 express 中使用套接字时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58756713/