简体   繁体   中英

Socket.io bug after success request

Guys. Expected some bug with my socket.io, So. all work fine: Below you can see the code example:

Server (Node.js):

controller:

.put('/user', jwtMiddleware, (req, res, next) => userService.updateUser(req.user.id, req.body.imageId, req.body)
    .then(data => res.send(data))
    .catch(err => {
      console.log(err.message); <------ LOOK AT THIS (1)
      req.io.to(req.user.id).emit('user_data', err.message); // notify a user if username or email isn't unique
      res.status(400).send();
      next();
    }));

PS io injected to the request object.

userService.updateUser.js:

export const updateUser = async (userId, imageId, user) => {
  const userByName = await userRepository.getByUsername(user.username);

  if (userByName !== null && userByName.id !== userId) {
    throw new Error('Username should be unique');
  }

  const { id } = await userRepository.updateById(userId, {
    ...user,
    imageId
  });
  return getUserById(id);
};

Below you can see client code (React.js):

socket.on('user_data', message => {
   console.log(message); <----- LOOK AT THIS (2)
   NotificationManager.info(message);
});

And now time for explaining the problem.

a) When I send my user object from client to controller with 'username' that has already existed in the DB, I wonderful receive response on the client and my socket on the client in the places (1) (2) well work.

b) But when I send my user object from the client to the controller with 'username' that doesn't exist in the DB, it will fine save in the DB and after that, if I send a request as in point (a), I won't receive a response on the client. My socket on the server in a place (1) WORK CORRECTLY and in a place (2) ISN'T WORK.

Why has it happened?

These are the reasons I can think of why you wouldn't receive the message from when you do this:

req.io.to(req.user.id).emit('user_data', err.message);
  1. req.user or req.user.id is not what you expect it to be and thus req.io.to(req.user.id) doesn't find a valid user connection to send to.

  2. The target page does not yet have an appropriate socket.io connection with the selected id value

  3. When the request receives back the 400 status, it is not then in a state where it can receive your socket.io message (we'd have to see the client-side code to comment more on that). For example, if it reloads the page, then that old socket.io connection would be torn down and a new one with a different socket.id would be created.

FYI, you can step into req.io.to(req.user.id) in the debugger and see exactly how many matching socket.io connections it finds.


Also, FYI, you should not be called next() after doing res.status(400).send(); . That will probably generate a warning as you will end up trying to send two responses to the same request. Remove the call to next() .

I guess it is because in the success response you're not emitting any socket event.

.put('/user', jwtMiddleware, (req, res, next) => userService.updateUser(req.user.id, req.body.imageId, req.body)
    .then(data => {
      req.io.to(req.user.id).emit('user_data', 'User Created Successfully')
      res.send(data)
    })
    .catch(err => {
      console.log(err.message); <------ LOOK AT THIS (1)
      req.io.to(req.user.id).emit('user_data', err.message); // notify a user if username or email isn't unique
      res.status(400).send();
      next();
    }));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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