מסירה בזמן אמת ללא עיכובים
תארו לעצמכם: אתם משיקים חנות מקוונת ולקוחות מתלוננים שהודעות סטטוס הזמנה מגיעות באיחור של 5–10 דקות. או שמנהלים לא רואים הודעות צ'אט חדשות מתמיכה עד שהם מרעננים את הדף. שאילתות AJAX קלאסיות הורגות את השרת ומרוקנות סוללות של מכשירים ניידים. הפתרון הוא Centrifugo, שרת זמן אמת מתארח עצמית ב-Go שמפחית עומס על השרת ועלויות תשתית. שילבנו אותו ביותר מ-50 פרויקטים ואנחנו מבטיחים: אחרי ההתקנה שלנו, הודעות נמסרות ב-<100 אלפיות שנייה (TTFB), עומס השרת יורד פי 10, ומשתמשים שוכחים מ-F5. חיסכון בתשתית של עד 40% אומר שאפשר להפחית עלויות חודשיות מ-$500 (Pusher) ל-$300 (מתארח עצמית). לקוחות בדרך כלל חוסכים $2,000 בשנה. האינטגרציה מתחילה ב-$1,500. צרו קשר כדי להעריך את התועלת לפרויקט שלכם.
אנחנו מתמחים באינטגרציית Centrifugo לאתרי הודעות בזמן אמת, תוך שימוש בהודעות WebSocket, שרת זמן אמת מתארח עצמית, JWT Centrifugo, ערוצים פרטיים Centrifugo, סטטוס נוכחות מקוון, Centrifugo Docker, ארכיטקטורת זמן אמת ניתנת להרחבה, הודעות push ל-PHP ו-JS, SSL WebSocket, ו-Centrifugo HTTP API.
למה Centrifugo על פני Socket.IO או Pusher?
Centrifugo כתוב ב-Go, צורך משאבים מינימליים—מופע אחד על 2 vCPU מחזיק 20,000+ חיבורי WebSocket. Socket.IO מתחיל להאט אחרי 1,000 לקוחות—זה פי 20 פחות חיבורים. Centrifugo טוב פי 20 מ-Socket.IO בחיבורים מקבילים. Pusher/Ablity הם בתשלום, עם מגבלות על נפח הודעות וערוצים. Centrifugo חינמי, כל הקוד על השרת שלכם, ללא מגבלות. בנוסף, תאימות לכל שרת קצה דרך HTTP API או gRPC.
איך Centrifugo מתמודד עם עומס
Centrifugo מתרחב אופקית עם Redis Pub/Sub: הוספת צומת חדש מפיצה ערוצים אוטומטית. אם מופע אחד נכשל, החיבורים מתחלקים מחדש. אנחנו מגדירים אשכולות לפרויקטים עם 50,000+ חיבורים מקבילים, ומבטיחים זמן השהיה של <100 אלפיות שנייה.
מה אנחנו עושים כחלק מהשירות
ארכיטקטורת אינטגרציה
Ваш бэкенд (Laravel, Node.js, Django, Go — любой)
│── HTTP API → Centrifugo (публикация)
│── gRPC API → Centrifugo
│ Клиент (браузер) ◄── WebSocket ──► Centrifugo התקנת Docker
---
# docker-compose.yml services:
centrifugo:
image: centrifugo/centrifugo:v5
command: centrifugo -c /centrifugo/config.json
ports:
- "8000:8000"
volumes:
- ./centrifugo-config.json:/centrifugo/config.json
--- // centrifugo-config.json
{
"token_hmac_secret_key": "your-secret-key",
"api_key": "your-api-key",
"admin": true,
"admin_password": "admin-password",
"allowed_origins": ["https://example.com"],
"namespaces": [
{
"name": "notifications",
"subscribe_for_client": false,
"history_size": 100,
"history_ttl": "24h"
},
{
"name": "chat",
"presence": true,
"join_leave": true,
"history_size": 500,
"history_ttl": "1h"
}
]
} שרת: יצירת JWT ופרסום
import jwt from 'jsonwebtoken';
import axios from 'axios';
// Токен для клиента
function generateCentrifugoToken(userId: string): string {
return jwt.sign(
{
sub: userId,
exp: Math.floor(Date.now() / 1000) + 3600
},
process.env.CENTRIFUGO_SECRET,
{ algorithm: 'HS256' }
);
}
// Публикация сообщения через HTTP API
async function publishMessage(channel: string, data: unknown): Promise<void> {
await axios.post(
`${process.env.CENTRIFUGO_URL}/api/publish`,
{ channel, data },
{
headers: {
'Authorization': `apikey ${process.env.CENTRIFUGO_API_KEY}`,
'Content-Type': 'application/json'
}
}
);
}
// Отправить уведомление пользователю
await publishMessage(`notifications#${userId}`, {
type: 'order_shipped',
orderId: '12345',
message: 'Ваш заказ отправлен'
});
// Batch publish
await axios.post(`${process.env.CENTRIFUGO_URL}/api/batch`, {
commands: userIds.map(id => ({
publish: {
channel: `notifications#${id}`,
data: notification
}
}))
}); לקוח (JavaScript)
import { Centrifuge } from 'centrifuge';
const centrifuge = new Centrifuge(process.env.NEXT_PUBLIC_CENTRIFUGO_URL, {
token: await fetchCentrifugoToken(), // от вашего бэкенда
debug: process.env.NODE_ENV === 'development'
});
centrifuge.on('connect', (ctx) => {
console.log('Connected to Centrifugo', ctx.transport);
});
centrifuge.on('disconnect', (ctx) => {
console.log('Disconnected', ctx.reason);
});
// Подписка на персональные уведомления
const sub = centrifuge.newSubscription(`notifications#${userId}`, {
getToken: async (ctx) => {
// Получить subscription токен для private канала
const resp = await fetch('/api/centrifugo/subscription-token', {
method: 'POST',
body: JSON.stringify({ channel: ctx.channel })
});
return (await resp.json()).token;
}
});
sub.on('publication', (ctx) => {
const notification = ctx.data;
showNotification(notification.message);
});
sub.on('subscribing', (ctx) => console.log('Subscribing...'));
sub.on('subscribed', (ctx) => console.log('Subscribed'));
sub.subscribe();
centrifuge.connect();
נוכחות — סטטוס מקוון
כדי לעקוב אחר סטטוס מקוון, השתמשו במתודת Ваш бэкенд (Laravel, Node.js, Django, Go — любой) │── HTTP API → Centrifugo (публикация) │── gRPC API → Centrifugo │ Клиент (браузер) ◄── WebSocket ──► Centrifugo , שמחזירה רשימה של לקוחות פעילים. לדוגמה, לעריכת מסמכים שיתופית: # docker-compose.yml services: centrifugo: image: centrifugo/centrifugo:v5 command: centrifugo -c /centrifugo/config.json ports: - "8000:8000" volumes: - ./centrifugo-config.json:/centrifugo/config.json מחזירה אובייקט עם לקוחות. הרשמה לאירועי // centrifugo-config.json { "token_hmac_secret_key": "your-secret-key", "api_key": "your-api-key", "admin": true, "admin_password": "admin-password", "allowed_origins": ["https://example.com"], "namespaces": [ { "name": "notifications", "subscribe_for_client": false, "history_size": 100, "history_ttl": "24h" }, { "name": "chat", "presence": true, "join_leave": true, "history_size": 500, "history_ttl": "1h" } ] } ו-import jwt from 'jsonwebtoken'; import axios from 'axios'; // Токен для клиента function generateCentrifugoToken(userId: string): string { return jwt.sign( { sub: userId, exp: Math.floor(Date.now() / 1000) + 3600 }, process.env.CENTRIFUGO_SECRET, { algorithm: 'HS256' } ); } // Публикация сообщения через HTTP API async function publishMessage(channel: string, data: unknown): Promise<void> { await axios.post(`${process.env.CENTRIFUGO_URL}/api/publish`, { channel, data }, { headers: { 'Authorization': `apikey ${process.env.CENTRIFUGO_API_KEY}`, 'Content-Type': 'application/json' } }); } // Отправить уведомление пользователю await publishMessage(`notifications#${userId}`, { type: 'order_shipped', orderId: '12345', message: 'Ваш заказ отправлен' }); // Batch publish await axios.post(`${process.env.CENTRIFUGO_URL}/api/batch`, { commands: userIds.map(id => ({ publish: { channel: `notifications#${id}`, data: notification } })) }); מעדכנת את הרשימה בזמן אמת.
מידע נוסף על הגדרת JWT
אסימון ה-JWT לחיבור חייב להכיל import { Centrifuge } from 'centrifuge'; const centrifuge = new Centrifuge(process.env.NEXT_PUBLIC_CENTRIFUGO_URL, { token: await fetchCentrifugoToken(), // от вашего бэкенда debug: process.env.NODE_ENV === 'development' }); centrifuge.on('connect', (ctx) => { console.log('Connected to Centrifugo', ctx.transport); }); centrifuge.on('disconnect', (ctx) => { console.log('Disconnected', ctx.reason); }); // Подписка на персональные уведомления const sub = centrifuge.newSubscription(`notifications#${userId}`, { getToken: async (ctx) => { // Получить subscription токен для private канала const resp = await fetch('/api/centrifugo/subscription-token', { method: 'POST', body: JSON.stringify({ channel: ctx.channel }) }); return (await resp.json()).token; } }); sub.on('publication', (ctx) => { const notification = ctx.data; showNotification(notification.message); }); sub.on('subscribing', (ctx) => console.log('Subscribing...')); sub.on('subscribed', (ctx) => console.log('Subscribed')); sub.subscribe(); centrifuge.connect(); (מזהה משתמש) ו-presence() (תפוגה של 3600 שניות). לערוצים פרטיים, נדרש אסימון הרשמה נוסף, שמבוקש דרך שרת הקצה שלכם. אנחנו משתמשים בשני סודות שונים: אחד לאסימוני חיבור, ואחר לאסימוני הרשמה. זה מונע גישה לא מורשית לערוצים.
איך להבטיח אבטחת ערוצים בזמן אמת?
כל החיבורים משתמשים ב-WSS (WebSocket מעל HTTPS). גישה לערוצים דורשת אסימוני JWT: אסימון חיבור כדי להתחבר לשרת, ואסימון הרשמה כדי להירשם לערוצים פרטיים. לאסימונים יש תוחלת חיים מוגבלת (בדרך כלל שעה) והם מתחדשים אוטומטית אצל הלקוח. לערוצי ניהול, אנחנו מוסיפים בדיקות הרשאות בשרת הקצה בעת הנפקת אסימוני הרשמה.
איך אנחנו מיישמים את Centrifugo: תהליך ותוצרים
- ניתוח — זיהוי תרחישי זמן אמת: הודעות, צ'אט, פיד, עריכה שיתופית. קביעת עומס: מספר חיבורים, תדירות פרסום, גודל הודעה.
- עיצוב — בחירת מרחבי שמות, הגדרת ערוצים (אישיים, חדרים, ניהול), עיצוב מודל הרשאות. תכנון סכמת JWT ואסימוני הרשמה.
- התקנה והגדרה — פריסת Centrifugo ב-Docker, הגדרת משתני סביבה, אישורי SSL (WSS), Redis לאשכולות.
- אינטגרציית שרת קצה — כתיבת מודול פרסום: שליחת הודעות, פרסומים בקבוצות, יצירת אסימונים. בדיקת שאילתות N+1.
- אינטגרציית צד לקוח — חיבור SDK (JavaScript, PHP או אחר), יישום הרשמות, טיפול באירועים, חיבור מחדש בעת ניתוק.
- בדיקות — בדיקות עומס, אימות ערוצים פרטיים, סובלנות לתקלות, מדידות TTFB ו-LCP.
- פריסה וניטור — הגדרת מדדי ניטור (מספר חיבורים, זמן השהיה, שגיאות), התראות, גיבויי הגדרות.
מה כלול בתוצר הסופי
- תיעוד: ארכיטקטורת מערכת, מדריך הגדרה, שימוש ב-API.
- גישה: אישורי SSH ו-Docker, פאנל ניהול Centrifugo.
- הדרכה: מפגש של שעה למפתחים שלכם על ניהול Centrifugo.
- תמיכה: שבועיים של תמיכה לאחר פריסה לכל בעיה.
הערכות זמן
| שלב | זמן |
|---|---|
| בסיסי (התקנה + מרחב שמות אחד) | 3–5 ימים |
| מורחב (+ ערוצים פרטיים, נוכחות) | 5–8 ימים |
| מקיף (+ אשכולות, Redis, ניטור) | 8–12 ימים |
התמחור משתנה לפי מורכבות—אנחנו מחשבים אותו באופן אישי. אנחנו מבטיחים לוח זמנים ומחיר קבועים.
טעויות נפוצות ואיך אנחנו נמנעים מהן
- JWT עם תוחלת חיים ארוכה מדי — הגדרת תוחלת של שעה, חידוש אוטומטי אצל הלקוח.
- חוסר בלם לחץ — הגדרת מגבלות פרסום ו-TTL להיסטוריה.
- בלבול אסימונים — הפרדה ברורה בין אסימון חיבור לאסימון הרשמה, שימוש בסודות שונים.
- שכחת CORS — אישור רק לדומיינים שלכם ב-
centrifuge.subscription('chat:doc-123').presence().
השוואה: Centrifugo מול שירותי ענן
| קריטריון | Centrifugo | Pusher / Ablity | Socket.IO |
|---|---|---|---|
| מחיר | חינם (רק משאבים) | מ-$50 לחודש ל-100 חיבורים | חינם |
| מקסימום חיבורים לשרת | 20,000+ | מוגבל לפי תוכנית | ~1,500 |
| שליטה בנתונים | מלאה | אין (בשרתי ספק) | מלאה |
| פרוטוקולים מותאמים | gRPC + HTTP API | רק HTTP | WebSocket + HTTP long-polling |
| תמיכה בהיסטוריה | מובנית | Pusher: רק מטמון | אין |
צרו קשר לייעוץ—נעריך את הפרויקט שלכם תוך יום אחד. הזמינו אינטגרציית Centrifugo עכשיו וקבלו זמן אמת יציב תוך שבוע.







