Files
modstagram-back/utils/presence.js
payacom 3f416a7a60 full
2026-08-31 20:45:41 +03:30

49 lines
1.9 KiB
JavaScript

const { getRedisClient } = require('./redisClient')
// وضعیتِ «آنلاینِ لحظه‌ای» (نه last_online، که توی Mongo ذخیره می‌شه و throttle-شده‌ست) —
// این کلید فقط توی Redis زندگی می‌کنه، هیچ‌جا persist نمی‌شه، و منبعِ حقیقتِ «الان
// آنلاینه یا نه» هم از سوکت هم از هر درخواستِ HTTPِ احرازهویت‌شده رفرش می‌شه
const PRESENCE_TTL_SECONDS = 90
function key (userId) {
return `presence:online:${userId}`
}
async function markOnline (userId) {
const redis = getRedisClient()
if (!redis || !userId) return
try {
await redis.set(key(userId), '1', { EX: PRESENCE_TTL_SECONDS })
} catch (err) {
console.error('[presence] markOnline error:', err.message)
}
}
// موقعِ قطع‌شدنِ سوکت صدا زده می‌شه تا انتقال به «آفلاین» فوری‌تر باشه، نه اینکه تا
// انقضای TTL (۹۰ ثانیه) صبر کنه — best-effort، اگه کاربر یه سوکتِ دیگه (تبِ دیگه/
// دستگاهِ دیگه) هم داشته باشه، همون یکی دوباره presence رو رفرش می‌کنه
async function markOffline (userId) {
const redis = getRedisClient()
if (!redis || !userId) return
try {
await redis.del(key(userId))
} catch (err) {
console.error('[presence] markOffline error:', err.message)
}
}
// null یعنی نامشخص (Redis در دسترس نیست) — صدازننده باید به last_online-محورِ Mongo برگرده
async function isOnline (userId) {
const redis = getRedisClient()
if (!redis || !userId) return null
try {
const val = await redis.get(key(userId))
return val != null
} catch (err) {
console.error('[presence] isOnline error:', err.message)
return null
}
}
module.exports = { markOnline, markOffline, isOnline, PRESENCE_TTL_SECONDS }