P
P
pavuuuk2019-07-15 10:44:28
Node.js
pavuuuk, 2019-07-15 10:44:28

How to pass username to client side using socket.io?

This code is not complete, but I think this is enough. I want to get the username from mongoDB by session id and send that username to the client. Everything seems to work, but when I exit and delete the session, the error Cannot read property 'user' of undefined takes off, in this line: const id = session.user. That is, sid still exists after the exit and the loadUser function is executed. If I put an if (session) {...} check in loadUser, then everything is fine. But it still seems to me that I'm doing something wrong and it can be done somehow differently.
app.js

let
  express	     = require('express'),
  http	             = require("http"),
        config	     = require("./config/config"),
  cookieParser = require("cookie-parser"),
  mongoose    = require("./libs/db/mongoose"),
  session         = require("express-session"),
  MongoStore = require("connect-mongo")(session),
  cookie          = require("cookie"),
  app		     = express();

let mongooseStore = new MongoStore({mongooseConnection: mongoose.connection});

app.use(session({
  secret: config.session.secret,
  key: config.session.key,
  cookie: config.session.cookie,
  store: mongooseStore
  resave: false,
  saveUninitialized: false;
}));

const server = http.createServer(app);
const io = require("socket.io")(server, {
  origins: "http://127.0.0.1:5500/*"
});

function loadUser(sid, next, socket) {
  mongooseStore.load(sid, (err, session) => {
    if (err) {
      next(err);
    }

    const id = session.user;
    User.findById(id, (err, foundUser) => {
      if (err) {
        next(err);
      }
      socket.handshake.session = session;
      socket.handshake.user = foundUser;

                        next();	
    });
  })
}

io.use(function(socket, next) {
   
    var handshakeData = socket.request;
    handshakeData.cookies = cookie.parse(handshakeData.headers.cookie || "");
    var sidCookie = handshakeData.cookies[config.session.key];
    var sid = cookieParser.signedCookie(sidCookie, config.session.secret); // Id of session
  
  loadUser(sid, next, socket);

});


io.on("connection", (socket) => {
  
  if (socket.handshake.user) {
    var username = socket.handshake.user.username;
  }

  socket.on("Message", (text, cb) => {
    if (!username) {
      socket.emit("Error", {message: "User is not defined"});
    } else {
      let data = {text, username};
      socket.broadcast.emit("Message", data);
      cb(data);
    }
  });

});

server.listen(config.port, () => log.debug("Server is running"));

logout.js
exports.post = function(req, res) {
    
    req.session.destroy(() => {

        res.redirect("/");

    });
}

And yet, when I sit on two pages, and then go out on one, then I still count on the other. Found how to fix it. You just need to generate an event on logout, and process it on app.js. Get all clients there let clients = io.sockets.clients() and iterate over them, checking client.handshake.session.id, but there is no handshake in client. I don't understand anything here

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Skibin, 2019-07-15
@pavuuuk

To organize all sockets - when connecting, throw it into the "room" with its "userid". Thus, you can emit the desired event for all sockets of our user. Also, following the example of the same passport - in the middleware for the socket - if the user is authorized - drop it into the user's socket and it will be available to you in the following places.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question