full
This commit is contained in:
48
utils/presence.js
Normal file
48
utils/presence.js
Normal file
@@ -0,0 +1,48 @@
|
||||
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 }
|
||||
Reference in New Issue
Block a user