Socket.io: события запускаются дважды, если используются внутри маршрута express - PullRequest
0 голосов
/ 03 апреля 2020

Я работаю над приложением чата в socketio. Проблема, в которой я застрял, заключается в том, что, если я помещаю свой io.on('connection', ..}) блок вне express маршрута app.get('/chat'), все работает нормально, но когда я помещаю его в маршрут /chat. все внутри соединения запускается дважды.

сервер. js

 // On new connection
 io.on("connection", socket => {
      console.log('Socket ID: ' + socket.id);
      // I want the user object (inside /chat route) to be available here..
 })

// @route:chat
app.get("/chat", auth, async (req, res) => {
    const user = User.findbyId(req.userId);
    // socket.io part moved outside the route

    res.render('chat', {})
})

Вывод по первому запросу /chat:

Socket ID: 5e82d1a21c9d4400003e9bce

Вывод на второй запрос /chat:

Socket ID: 5e82d1a21c9d4400003e9bce --> this is repeating
Socket ID: 5e82d1a21c9d4400003e9bc4

И так далее, если я продолжаю запрашивать /chat.

Есть идеи, как решить эту проблему?

1 Ответ

1 голос
/ 03 апреля 2020

Обычно операции socketIO не должны зависеть от маршрута express. Если вы хотите, чтобы пользователь присоединился к соединению socketIO, это должно быть сделано через обработчики событий SocketIO. Ваш интерфейс должен инициировать соединение и передать некоторую идентификацию SocektIO, если вы хотите связать «пользователя» с этим сокетом.

Я не знаю, как ваше приложение обрабатывает аутентификацию, но обычной практикой является передача токена установлению соединения SocketIO:

const socket = IO.connect('http://localhost:8000', {
    query: {
      token//This token will be available on the server.
    }
  });

Итак, на вашем сервере:

const middleware = async (socket,next)=>{
    const token = socket.handshake.query.token;//Now you have the user token, which presumably contains the user ID.

    const verifiedUser = await getUserByToken(token);//Let's say this returns a user object, if the token is valid, false if not.
    // Let's assume that behind the scenes this function also calls User.findbyId(id);

    if(verifiedUser){
        socket.userObject = verifiedUser;//You can place the userObject on the token object, to be used later.
        next()//Will allow the "connection" event to proceed.
    }else{
        next(new Error('INVALID_CREDENTIALS'))//Will cause the on("error") event to fire in the front-end, passing this error.
        //The on("connection") event here will not fire.
    }
}

io.use(middleware)

io.on('connection', async (socket) => { 

    //This runs only if middleware is "successful".


})

Я не знаю, отвечает ли это на ваши вопросы, но это пример того, как могут выглядеть отношения между сокетами и пользователями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...