full
This commit is contained in:
@@ -1,19 +1,49 @@
|
||||
const jwt = require('jsonwebtoken')
|
||||
const UserModel = require('../models/UserModel')
|
||||
const { getRedisClient } = require('../utils/redisClient')
|
||||
const { markOnline } = require('../utils/presence')
|
||||
|
||||
// این میدلور روی *هر* درخواستِ احرازهویتشده اجرا میشه (app.use سراسری) — قبلاً
|
||||
// یعنی هر درخواست یه findById+save کاملِ Mongo میزد، حتی برای کاربری که پشتِسرِهم
|
||||
// صدها درخواست در دقیقه میفرسته. الان: وضعیتِ «آنلاینِ لحظهای» توی Redis با TTLِ
|
||||
// کوتاه نگه داشته میشه (هر درخواست رفرش میشه، تقریباً رایگان — utils/presence.js)،
|
||||
// و نوشتنِ last_online توی Mongo (برای «آخرین بازدید» که جاهای دیگهی اپ میخونن)
|
||||
// throttle میشه به حداکثر یکبار در هر ۶۰ ثانیه برای هر کاربر
|
||||
const MONGO_SYNC_TTL_SECONDS = 60
|
||||
|
||||
async function syncLastOnlineToMongo (userId) {
|
||||
const user = await UserModel.findById(userId).select('ghost_mode account_status')
|
||||
if (user && !user.ghost_mode && user.account_status !== 'deactivated') {
|
||||
await UserModel.updateOne({ _id: userId }, { last_online: new Date() })
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = async (req, res, next) => {
|
||||
if (req.header && req.header('Authorization')) {
|
||||
const token = await req.header('Authorization').split(' ')[1]
|
||||
const decodedToken = await jwt.verify(token, process.env.APP_SECRET)
|
||||
const user = await UserModel.findById(decodedToken.id)
|
||||
if (user) {
|
||||
try {
|
||||
user.last_online = new Date()
|
||||
await user.save() // ذخیره تغییرات در دیتابیس
|
||||
} catch (error) {
|
||||
// بررسی و پردازش خطاها
|
||||
console.error('Error updating last online time:', error)
|
||||
try {
|
||||
const token = req.header('Authorization').split(' ')[1]
|
||||
const decodedToken = jwt.verify(token, process.env.APP_SECRET)
|
||||
const userId = String(decodedToken.id)
|
||||
const redis = getRedisClient()
|
||||
|
||||
if (redis) {
|
||||
await markOnline(userId)
|
||||
|
||||
const acquiredSyncLock = await redis.set(
|
||||
`presence:sync:${userId}`,
|
||||
'1',
|
||||
{ NX: true, EX: MONGO_SYNC_TTL_SECONDS }
|
||||
)
|
||||
if (acquiredSyncLock) {
|
||||
await syncLastOnlineToMongo(userId)
|
||||
}
|
||||
} else {
|
||||
// Redis در دسترس نیست — همون رفتارِ قبلی، مستقیم Mongo (fallback امن، کندتر
|
||||
// ولی درست) تا وقتی Redis دوباره وصل بشه
|
||||
await syncLastOnlineToMongo(userId)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error updating last online time:', error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user