简体   繁体   English

在 express 中使用套接字时出现问题

[英]Problem with socket when using it in express

I have a problem with the socket in my program.我的程序中的套接字有问题。 export the "io" connection and although I can broadcast from any part of the normal program (just by referring to "io"), I cannot use "socket" and broadcast with it unless it is within the same connection of "io."导出“io”连接,虽然我可以从普通程序的任何部分广播(仅通过引用“io”),但我不能使用“socket”并用它广播,除非它在“io”的同一连接内。 I would like to know how to use socket from any other part of the program, with functions such as "socket.emit ()" or "socket.broadcast.emit" etc. Or how to call this one.我想知道如何从程序的任何其他部分使用套接字,例如“socket.emit()”或“socket.broadcast.emit”等函数。或者如何调用这个。

This is my index.js:这是我的 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);

my managersocket.js:我的 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;

This is where I would like to use the socket or at least call the function.这是我想使用套接字或至少调用 function 的地方。

and User.js:和 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; };

same is the repository where the whole code is同样是整个代码所在的存储库

https://github.com/proxirv/Socket.io-router

socket is a temporary object that exists only for the duration of one particular client connection. socket是一个临时的 object,仅在一个特定的客户端连接期间存在。 And, there can be zillions of them (one or more for each connected client).而且,它们可能有无数个(每个连接的客户端一个或多个)。 As such, you don't just export one socket or stuff it in a global and try to use that everywhere.因此,您不只是导出一个socket或将其填充到全局中并尝试在任何地方使用它。

So, if what you're trying to do is to access the socket.io connection for the user that you just received an http request for, that's a bit more complicated and there are several different ways to approach it.因此,如果您要做的是访问您刚刚收到 http 请求的用户的 socket.io 连接,那么这有点复杂,并且有几种不同的方法可以接近它。

One approach, I've used before is shown below:我之前使用过的一种方法如下所示:

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

Here are the steps in that concept:以下是该概念的步骤:

  1. Set up express-session for regular http connections.为常规 http 连接设置快速会话。 This gives you a place to store stuff that belongs to one particular client (keyed by a cookie)这为您提供了一个存储属于某个特定客户端的东西的地方(由 cookie 键入)
  2. Set up express-session for the socket.io connection so you can also have access to express-session data in socket.io connections.为 socket.io 连接设置快速会话,以便您还可以访问 socket.io 连接中的快速会话数据。
  3. When a socket.io connection happens, store the socket.id in the sesssion.当发生 socket.io 连接时,将 socket.id 存储在会话中。 This makes the socket.id available for future http requests from that specific client这使得 socket.id 可用于来自该特定客户端的未来 http 请求
  4. When some future http request comes in from that client, you can reach into the session, get the socket.id value (which is just a string) and then use that to get the socket for that user and once you have the socket, you can use socket.emit() to send data just to that user.当一些未来的 http 请求来自该客户端时,您可以进入 session,获取 socket.id 值(这只是一个字符串),然后使用它来获取该用户的套接字,一旦你有了套接字,你可以使用socket.emit()仅向该用户发送数据。

If you didn't have other reasons for using express-session, you could also just put the socket.id into a cookie all by itself when the socket.io connection connects and then get the socket.id from the cookie during your http request.如果您没有其他使用 express-session 的原因,您也可以在 socket.io 连接连接时将 socket.id 单独放入 cookie,然后在 http 请求期间从 cookie 中获取 socket.id。

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

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