מחוון נוכחות מקוונת בזמן אמת: מדריך יישום

משתמשים לא תמיד יודעים אילו עמיתים או לקוחות נמצאים כרגע באתר, מה שמאט את התקשורת ומפחית מעורבות. אנחנו מיישמים Presence indicator שמציג את סטטוס הנוכחות של המשתתפים בזמן אמת. הצוות שלנו מטפל בכל המחזור—מאודיט ועד deployment ותמיכה—ומבטיח פעולה אמינה והרחבה של הפתרון יחד עם העסק שלכם.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
מחוון נוכחות מקוונת בזמן אמת: מדריך יישום
פשוט
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

כיצד לבנות מחוון נוכחות בזמן אמת לאתר שלך

הבעיה: משתמשים רואים תמונות פרופיל אבל לא יודעים מי מחובר כרגע

עבדנו על פרויקט — פלטפורמת קורסים מקוונת עם סמינרים חיים. המשתתפים התלוננו: "אני כותב למורה בצ'אט, אבל הם לא עונים — מסתבר שהם כבר לא מחוברים." זה אולי נראה טריוויאלי, אבל היעדר מחוון בזמן אמת הפחית את המעורבות ב-15%. יישמנו מחוון נוכחות ביומיים. עכשיו כולם רואים נקודה ירוקה ויודעים למי לשאול שאלה כרגע. במשך שלוש שנים, פרסנו יותר מ-50 פתרונות כאלה לצ'אטים, קורסים ופורטלים ארגוניים.

דופק דרך HTTP במקום WebSocket

אנחנו משתמשים בדופק דרך HTTP — אנו שולחים POST /api/presence/ping כל 30 שניות. אם אין פינג במשך 90 שניות, המשתמש נחשב לא מקוון. גישה זו פשוטה יותר מ-WebSocket ואינה דורשת חיבור קבוע. עבור רוב האתרים, זה מספיק. WebSocket מספק דיוק עד שנייה אבל דורש תשתית שרת וחיבור קבוע. הבחירה תלויה בתרחיש: לצ'אט — WebSocket, לרשימת משתתפים בקורס — דופק HTTP.

גישה דיוק מורכבות מתי להשתמש
WebSocket/SSE ~שנייה אחת גבוהה צ'אט, עריכה שיתופית
דופק HTTP ~60 שניות נמוכה פרופילים, רשימות משתתפים
נראה לאחרונה ~3 דקות נמוכה מאוד הגדרות פרטיות

Redis כאחסון האידיאלי לנוכחות

Redis מהיר פי 10 מ-PostgreSQL במהירות כתיבה למשימה זו ומסיר אוטומטית נתונים מיושנים ללא משימות רקע. כל קריאה לsetex יוצרת מפתח עם TTL של 90 שניות. אם המשתמש מפסיק לשלוח פינג, המפתח נעלם אוטומטית. כפי שצוין בתיעוד Redis, הפקודה SETEX מגדירה מפתח עם תפוגה אוטומטית. להלן יישום מפושט של השירות שלנו:

class PresenceService {
    private const TTL = 90;

    public function markOnline(int $userId, string $context = 'global'): void {
        Redis::setex("presence:{$context}:{$userId}", self::TTL, now()->timestamp);

        $wasOnline = Redis::exists("presence_flag:{$context}:{$userId}");
        if (!$wasOnline) {
            Redis::setex("presence_flag:{$context}:{$userId}", self::TTL + 10, 1);
            broadcast(new UserCameOnline($userId, $context));
        }
    }

    public function markOffline(int $userId, string $context = 'global'): void {
        Redis::del("presence:{$context}:{$userId}");
        Redis::del("presence_flag:{$context}:{$userId}");
        broadcast(new UserWentOffline($userId, $context));
    }

    public function getOnlineUsers(string $context = 'global'): array {
        $keys = Redis::keys("presence:{$context}:*");
        return array_map(fn($k) => (int) last(explode(':', $k)), $keys);
    }

    public function isOnline(int $userId, string $context = 'global'): bool {
        return (bool) Redis::exists("presence:{$context}:{$userId}");
    }
}
הסבר על הקוד הפרמטר `$context` מאפשר פיצול נוכחות בין סעיפים: `chat_room:42`, `course:17`, `global`. הפקודה `setex` מגדירה מפתח שפג תוקפו לאחר TTL שניות. הדגל `presence_flag` מונע אירועי שידור כפולים בכל פינג.

הפרמטר class PresenceService { private const TTL = 90; public function markOnline(int $userId, string $context = 'global'): void { Redis::setex("presence:{$context}:{$userId}", self::TTL, now()->timestamp); $wasOnline = Redis::exists("presence_flag:{$context}:{$userId}"); if (!$wasOnline) { Redis::setex("presence_flag:{$context}:{$userId}", self::TTL + 10, 1); broadcast(new UserCameOnline($userId, $context)); } } public function markOffline(int $userId, string $context = 'global'): void { Redis::del("presence:{$context}:{$userId}"); Redis::del("presence_flag:{$context}:{$userId}"); broadcast(new UserWentOffline($userId, $context)); } public function getOnlineUsers(string $context = 'global'): array { $keys = Redis::keys("presence:{$context}:*"); return array_map(fn($k) => (int) last(explode(':', $k)), $keys); } public function isOnline(int $userId, string $context = 'global'): bool { return (bool) Redis::exists("presence:{$context}:{$userId}"); } } מאפשר פיצול נוכחות בין סעיפים: $context, chat_room:42, course:17.

אירועי שידור מסנכרנים סטטוס

כאשר הסטטוס משתנה, אנו משדרים אירועי global ו-UserCameOnline. הם מכילים רק את מזהה המשתמש וההקשר. הלקוח מקבל את האירוע ומעדכן את הנקודה הירוקה. לשידור Laravel אנו משתמשים ב-Pusher או Redis + Socket.IO. דוגמה לאירוע:

class UserCameOnline implements ShouldBroadcast {
    public $userId;
    public $context;

    public function broadcastOn(): array {
        return [new PresenceChannel("presence.{$this->context}")];
    }
}

הלקוח נרשם לערוץ דרך Laravel Echo ומגיב להודעות.

למה לבחור TTL של 90 שניות?

ה-TTL צריך להיות פי שלושה ממרווח הפינג כדי לפצות על אובדני חיבור קצרים. עם פינג כל 30 שניות, TTL של 90 שניות מכסה שלושה פינגים שהוחמצו. אם החיבור נופל ל-40 שניות, המשתמש לא יוצא למצב לא מקוון. TTL קצר יותר (למשל, 60 שניות) גורם להבהוב סטטוס ברשתות לא יציבות. TTL ארוך יותר (120+ שניות) מעכב את זיהוי עזיבת המשתמש.

TTL התנהגות
60 שניות מהבהב לאחר החמצת 2 פינגים
90 שניות יציב, מגיב לאחר 3 שהוחמצו
120 שניות זיהוי איטי של ניתוק

הוראות שלב אחר שלב ליישום פינג דופק

  1. צור נקודת קצה POST עם אימות (למשל, Sanctum).
  2. בשירות PresenceService, יישם שיטות UserWentOffline/class UserCameOnline implements ShouldBroadcast { public $userId; public $context; public function broadcastOn(): array { return [new PresenceChannel("presence.{$this->context}")]; } } .
  3. בצד הלקוח, שלח פינג בטעינת הדף, ולאחר מכן חזור כל 30 שניות באמצעות setInterval.
  4. במטפל beforeunload, שלח בקשת ניתוק דרך navigator.sendBeacon (ראה תיעוד MDN).
  5. בשרת, עם קבלת פינג, עדכן את ה-TTL. אם אין פינג במשך 90 שניות, Redis מוחק את המפתח ונשלח אירוע ניתוק (יישם בדיקה בכל פינג או השתמש במשימת רקע).

טעויות נפוצות ביישום מחוון נוכחות

  • אי שימוש ב-navigator.sendBeacon — כאשר הכרטיסייה נסגרת, הבקשה לא יוצאת, והמשתמש נשאר מחובר עד שה-TTL פג. פתרון: השתמש ב-context.
  • אין הפרדת הקשר — כל המשתמשים רואים זה את זה ללא קשר לסעיף. פתרון: העבר UserCameOnline בכל פינג.
  • TTL קצר מדי — המשתמש מהבהב (מחובר/לא מקוון) בחיבורים לא יציבים. אנו ממליצים על TTL = פי 3 ממרווח הפינג.

מה כלול בעבודה

  • פיתוח נקודת קצה לדופק ושירות Redis
  • הגדרת אירועי שידור UserWentOffline, UserWentOffline
  • יישום המחוון בממשק המשתמש (נקודה / תג)
  • תיעוד API ואינטגרציה
  • הדרכת צוות לתחזוקה שוטפת

למהנדסים שלנו יש ניסיון של 5+ שנים עם Laravel ו-Vue/React. במשך 3 שנים, יישמנו יותר מ-50 פתרונות דומים לצ'אטים, קורסים ופורטלים ארגוניים. רקורד מוכח שלנו מבטיח יישום אמין.

לוחות זמנים ועלות

  • פינג דופק + Redis TTL + מחוון: 1–2 ימים (כ-$1,500–$3,000)
  • שידור בשינוי סטטוס: יום אחד (כ-$1,000)
  • ערוצי נוכחות דרך Laravel Echo: יום אחד (כ-$1,000)
  • נראה לאחרונה: 0.5 יום (כ-$500)
  • הגדרות פרטיות: +0.5 יום (כ-$500)

העלות מחושבת באופן אישי לפי מורכבות. צור קשר — נבדוק את הפרויקט שלך תוך יום עסקים אחד. קבל ייעוץ לפרויקט שלך — המהנדסים שלנו יעזרו לבחור את הפתרון האופטימלי. אנו מציעים אחריות של 100% שביעות רצון.