Bootstrap

02更新用户在线状态

1、场景

1、当用户主动退出登录

2、当用户关闭当前页面

3、当用户的session信息过期时

2、思路

1、前两个场景可以编写接口,前端在合适时机调用

router.post('/logout', async (req, res, next) => {
  await userModel.updateOne({ _id: req.session.userId }, { online: 0 })
  // 1:关闭窗口  2:退出登录
  if (req.body.type == 1) {
    res.json({ code: 0, msg: '操作成功' })
  } else if (req.body.type === 2) {
    req.session.destroy(() => {
      res.json({ code: 0, msg: '操作成功' })
    })
  }
})

2、第三个场景有多种思路

1、编写接口,检查用户的登录状态

router.post('/checkLogin', async (req, res, next) => {
  if (!req.session.userId) {
    res.json({ code: 401, msg: '用户未登录' })
    return
  }
  await userModel.updateOne({ _id: req.session.userId }, { online: 1 })
  res.json({ code: 0, msg: '处于登录状态' })
})

2、编写中间件。当用户请求时,检查登录状态

const sessionMiddleWare = async (req, res, next) => {
  if (!req.session.userId) {
    res.json({ code: 401, msg: '用户未登录' })
    return
  }
  next()
}

3、登录后,记录登录时间。定时遍历所有用户信息。当某个用户的登录时间+session有效时间等于当前时间的时候。更新用户登录状态

const userModel = require('../db/model/user')
const { SESSIONTIME } = require('../config/index')
let timer = null
const updateUsersOnlineStatus = async () => {
  try {
    const start = Date.now()
    const userData = await userModel.find({ online: 1, loginTime: { $lte: Date.now() - SESSIONTIME } })
    if (userData.length > 0) {
      const bulkOps = userData.map(user => ({
        updateOne: {
          filter: { _id: user._id },
          update: { online: 0 },
        },
      }))
      await userModel.bulkWrite(bulkOps)
    }
    const end = Date.now()
    const elapsed = end - start
    const nextInterval = Math.max(0, 1000 * 60 - elapsed) // Ensure next interval is at least 1 minute
    return nextInterval
  } catch (error) {
    console.error('Error updating user online status:', error)
    return 1000 * 60 // Retry after 1 minute on error
  }
}
const startOnlineStatusCheck = async () => {
  try {
    const interval = await updateUsersOnlineStatus()
    if (timer) {
      clearInterval(timer)
    }
    timer = setInterval(updateUsersOnlineStatus, interval)
  } catch (error) {
    console.error('Error starting online status check:', error)
  }
}

module.exports = startOnlineStatusCheck

;