49 lines
1.9 KiB
JavaScript
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 }
|