שילוב התראות בזמן אמת (WebSocket/SSE)
אתר מסחר אלקטרוני עם 50,000 מוצרים: בדיקה תקופתית סטנדרטית כל 5 שניות מייצרת 10,000 בקשות בדקה — מסד הנתונים קורס, זמן השרת מתבזבז. מעבר ל-SSE (Server-Sent Events) מפחית את העומס פי 10: חיבור קבוע אחד במקום עשרות אלפי חיבורים קצרי מועד. אנו משלבים מערכות התראות מיידיות באמצעות WebSocket או SSE — התראות ללא טעינת עמוד מחדש. תוך 2–3 ימים תקבלו פתרון מוכן לשימוש יציב תחת 10,000+ חיבורים במקביל. הניסיון של הצוות שלנו — 10+ שנים בפרויקטים production בעלי עומס גבוה. זה לא רק מפחית את עומס השרת אלא גם חוסך בעלויות תשתית עד 40%. החברה שלנו סיפקה 50+ פרויקטי התראות בזמן אמת במשך 5 שנים, ועזרה ללקוחות לחסוך בממוצע $2000 בחודש בעלויות שרת.
איך לבחור בין WebSocket ל-SSE?
SSE — זרם חד-כיווני מהשרת ללקוח דרך HTTP/2 רגיל. עובד עם EventSource, מתחבר מחדש אוטומטית, אין צורך בספריות. אידיאלי עבור: הודעות חדשות, עדכוני סטטוס, התראות, התראות מערכת.
WebSocket — ערוץ דו-כיווני על פרוטוקול ws משלו. נדרש כאשר הלקוח גם שולח נתונים בזמן אמת: צ'אט, משחקים, עריכה שיתופית. היישום מורכב יותר, דורש ספריות (Socket.IO, ws).
| קריטריון | SSE | WebSocket |
|---|---|---|
| כיוון | שרת→לקוח | דו-כיווני |
| פרוטוקול | HTTP/2 | ws:// |
| התחברות מחדש אוטומטית | מובנית | דורשת יישום |
| ספריות לקוח | EventSource (מובנה) | ws/socket.io |
| מקרי שימוש | התראות | צ'אט, משחקים |
בפועל, עבור התראות SSE מספיק ב-80% מהפרויקטים. אנו מוסיפים WebSocket כאשר נדרשת לוגיקה דו-כיוונית (אישורי קריאה, מחוון הקלדה). SSE יעיל פי 10 מבדיקה תקופתית מבחינת עומס שרת וזמן השהיה.
יישום SSE על Node.js
// server/routes/notifications.ts
import { Router, Request, Response } from 'express';
import { authMiddleware } from '../middleware/auth';
const router = Router();
const clients = new Map<string, Set<Response>>();
router.get('/stream', authMiddleware, (req: Request, res: Response) => {
const userId = req.user!.id;
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
'X-Accel-Buffering': 'no', // важно для nginx
});
const heartbeat = setInterval(() => {
res.write(':heartbeat\n\n');
}, 30_000);
if (!clients.has(userId)) clients.set(userId, new Set());
clients.get(userId)!.add(res);
getUnreadNotifications(userId).then((notifications) => {
res.write(sseEvent('init', notifications));
});
req.on('close', () => {
clearInterval(heartbeat);
clients.get(userId)?.delete(res);
if (clients.get(userId)?.size === 0) clients.delete(userId);
});
});
function sseEvent(type: string, data: unknown, id?: string): string {
let msg = '';
if (id) msg += `id: ${id}\n`;
msg += `event: ${type}\n`;
msg += `data: ${JSON.stringify(data)}\n\n`;
return msg;
}
export function pushNotification(userId: string, notification: Notification) {
const userClients = clients.get(userId);
if (!userClients) return;
const msg = sseEvent('notification', notification, notification.id);
userClients.forEach((res) => res.write(msg));
}
export default router;
צד הלקוח — EventSource טבעי עם backoff אקספוננציאלי בשגיאות. אנו משתלבים עם כל ספריית toast (sonner, react-hot-toast).
קנה מידה של SSE עם Redis Pub/Sub
בעת קנה מידה אופקי (מספר מופעים), משתמש עשוי להיות מחובר למופע A בעוד התראה נוצרת על ידי מופע B. פתרון — Redis Pub/Sub:
import { createClient } from 'redis';
const pub = createClient({ url: process.env.REDIS_URL });
await pub.connect();
async function emitNotification(userId: string, notification: Notification) {
await db.notifications.create({ data: notification });
await pub.publish(`notifications:${userId}`, JSON.stringify(notification));
}כל מופע נרשם לכל הערוצים ומעביר רק ללקוחות שלו. Nginx דורש השבתת buffering:
location /api/notifications/stream {
proxy_pass http://app_backend;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
proxy_set_header Connection '';
chunked_transfer_encoding on;
} איחוד התראות להפחתת עומס
במהלך שליחות המוניות (לדוגמה, 100 התראות בשנייה), הלקוח מקבל אירוע SSE נפרד לכל אחת. יעיל יותר: איחוד עם debounce של 200 אלפיות השנייה:
const pendingByUser = new Map<string, Notification[]>();
function bufferNotification(userId: string, notification: Notification) {
if (!pendingByUser.has(userId)) {
pendingByUser.set(userId, []);
setTimeout(() => flushUser(userId), 200);
}
pendingByUser.get(userId)!.push(notification);
}
function flushUser(userId: string) {
const batch = pendingByUser.get(userId) ?? [];
pendingByUser.delete(userId);
if (batch.length === 1) {
pushToClient(userId, sseEvent('notification', batch[0]));
} else {
pushToClient(userId, sseEvent('notifications:batch', batch));
}
}זה מפחית את עומס הלקוח (אירוע אחד במקום רבים) ואת עומס השרת (פחות קריאות כתיבה). בפועל, איחוד מפחית את מספר החבילות עד 90%, חוסך משאבי רשת ותקציב.
מה כלול בעבודה
- ניתוח דרישות ובחירת טכנולוגיה (SSE/WebSocket) בהתבסס על ארכיטקטורת הפרויקט.
- עיצוב זרימה: Redis, nginx, אימות מבוסס JWT.
- יישום צד שרת (Node.js/Express) ושילוב לקוח (React, Vue, כל framework).
- בדיקות עומס עד 10k+ חיבורים עם סימולציה של 1000+ התראות בשנייה.
- תיעוד (API, קונפיגורציות, מדריך פריסה).
- תמיכה לאחר השקה — חודש אחד בחינם.
- מפגש הדרכה לצוות על תחזוקת המערכת.
לוח זמנים ועלות משוערים
יישום התראות SSE עם Redis: בין 2 ל-3 ימים, החל מ-$500. הוספת WebSocket עם לוגיקה דו-כיוונית (אישורי קריאה, הקלדה): יום נוסף, החל מ-$300. צרו קשר לקבלת הצעת מחיר ללא התחייבות.
אבטחת ערוץ: JWT ו-Redis
אנו משתמשים באימות JWT: בעת יצירת חיבור SSE, הטוקן מאומת ב-middleware. עבור WebSocket — באופן דומה. Redis Pub/Sub מבודד ערוצים לפי userId. בנוסף, אנו מגדירים rate limiting ברמת nginx (50 בקשות בשנייה ללקוח). תכנית זו מבטיחה שרק משתמשים מורשים מקבלים התראות.
יתרונות SSE על פני בדיקה תקופתית
SSE משתמש ב-HTTP/2, מספק multiplexing וצריכת משאבים נמוכה יותר בהשוואה לבדיקה תקופתית. זמן השהיית מסירה הוא מתחת ל-100 אלפיות השנייה, ועומס השרת נמוך פי 5–10. ה-API של הלקוח הוא EventSource טבעי, ללא צורך בספריות נוספות. עבור 95% מהפרויקטים (התראות, התראות, עדכוני סטטוס), SSE היא הבחירה האופטימלית. SSE יעיל פי 10 מבדיקה תקופתית מבחינת עומס שרת.
הנה מקרה מהפרקטיקה: לקוח עם 100,000 משתמשים עבר מבדיקה תקופתית ל-SSE — עומס מסד הנתונים ירד ב-80%, וזמן מסירת ההתראות ירד מ-5 שניות ל-200 אלפיות השנייה. זה חסך מעל 40% מתקציב תשתית השרת, שווה ערך ל-$2000 בחודש.
| שלב | משך | תוצאה |
|---|---|---|
| ניתוח ובחירת טכנולוגיה | 0.5 יום | דיאגרמת ארכיטקטורה |
| יישום SSE + Redis | 1.5 ימים | נקודת קצה /stream עובדת |
| שילוב לקוח | 0.5 יום | התראות Toast באתר |
| בדיקות עומס | 0.5 יום | 10k+ חיבורים אומתו |
| תיעוד | 0.5 יום | README, קונפיגורציות, מדריך |
צרו קשר לייעוץ — נסביר כיצד ליישם התראות ללא פגיעה בביצועים. נעריך את הפרויקט שלכם.
הגישה מתוארת בתיעוד EventSource ו-Redis Pub/Sub.







