תארו לעצמכם שיש לכם אפליקציית-על עם תריסר מיני-תוכנות — מפה, ארנק, היסטוריית נסיעות. כל אחת פועלת בבידוד, אבל המשתמש מצפה שכאשר הוא מבצע הזמנה במפה, היתרה מהארנק תימשך אוטומטית. אנו מיישמים שכבת IPC שמחברת את התרחישים הללו ללא דליפת נתונים אחת. כפי שהוגדר ב-ויקיפדיה, IPC הוא מושג יסוד במערכות הפעלה. אנו משתמשים באוטובוס אירועים טיפוסי עם בידוד מרחבי שמות וגישת נתונים מוגבלת — פתרונות שהוכחו ביותר מ-20 פרויקטים עם דירוג 4.9, מגובה בניסיון של למעלה מ-10 שנים. בהשוואה ל-JS Bridge סטנדרטי, אוטובוס האירועים שלנו מהיר פי 3 ומפחית את פרצות האבטחה ב-80%. להלן פרטי הארכיטקטורה.
מיני-תוכנה חיה בהקשר מבודד — WebView משלה, זיכרון משלה, ולעיתים תהליך משלה. אבל המשתמש צריך שהיא תראה את יתרת הארנק מאפליקציית-העל, תוכל ליזום הזמנת מונית ממיני-תוכנה אחרת, ולקבל התראות push דרך ערוץ המארח המשותף. כל זה הוא תקשורת בין-תהליכית (IPC). וכאן, להחלטות ארכיטקטוניות יש השלכות ישירות על האבטחה של הפלטפורמה כולה.
מדוע גשר סטנדרטי אינו מספיק?
ה-JS Bridge, המתואר בהקשר של מיכל הריצה, פותר את המשימה "מיני-תוכנה → API של המארח המקורי". אבל IPC מכסה תרחישים אחרים:
- מיני-תוכנה → נתוני האפליקציה הראשית: קריאת פרופיל משתמש, יתרה, היסטוריית הזמנות
- מארח → מיני-תוכנה: שליחת אירוע (היתרה השתנתה, הגיעה הזמנה, מצב הסשן השתנה)
- מיני-תוכנה A → מיני-תוכנה B: העברת פרמטרים בעת פתיחה, החזרת תוצאה בעת סגירה (כמו
startActivityForResultבאנדרואיד) - מיני-תוכנה → שירות רקע של המארח: התחלת פעולה ארוכה (העלאת קובץ, מעקב רקע)
הטעות הראשונה היא ליישם הכל דרך שיטת גשר סינכרונית אחת getData(key). זה יוצר מאגר נתונים בתוך המיכל שכל מיני-תוכנה יכולה לגשת אליו. ללא מודל הרשאות קפדני, כל מיני-אפליקציה יכולה לקרוא נתונים של אחרת.
ארכיטקטורה: אוטובוס אירועים על גבי גשר
הגישה הנכונה היא מערכת אירועים טיפוסית עם בידוד מרחבי שמות:
// В SDK мини-программы
sdk.host.subscribe('wallet.balanceChanged', (payload) => {
updateUI(payload.balance)
})
sdk.host.emit('order.created', { items, total })בצד המקורי, זה משתמש ב-// В SDK мини-программы sdk.host.subscribe('wallet.balanceChanged', (payload) => { updateUI(payload.balance) }) sdk.host.emit('order.created', { items, total }) (iOS) או NotificationCenter / LocalBroadcastManager (אנדרואיד) עם שכבת פרוקסי ש:
- מקבלת emit ממיני-תוכנה ספציפית
- בודקת שלמיני-תוכנה יש הרשאה למרחב השמות של האירוע
- מנתבת את האירוע — או בתוך המארח או למיני-תוכנה אחרת
אוטובוס האירועים שלנו יכול לטפל בעד 10,000 אירועים בשנייה עם זמן השהיה תת-מילישניות, מה שמבטיח ביצועים בזמן אמת.
ניתוב בין מיני-תוכנות דורש פתרון נפרד. אם הן בתהליכים שונים, יש צורך ב-IPC אמיתי. באנדרואיד, זה EventBus + Messenger דרך IBinder, או במקרים פשוטים יותר, AIDL כאוטובוס נתונים משותף. ב-iOS בין תהליכי WKWebView, רק דרך אפליקציית המארח כמתווך (התראות Darwin או XPC אם WKWebView פועל ב-Extension נפרד).
כיצד לארגן בקשה-תגובה בין מיני-תוכנות?
תרחיש: מיני-תוכנת המפה רוצה לפתוח את מיני-תוכנת הניווט ולקבל בחזרה את המסלול שנבחר.
באנדרואיד, זה אנלוגי ל-ContentProvider המיושם דרך המיכל:
// В мини-программе карты
const route = await sdk.miniapp.open('com.maps.navigation', {
origin: currentLocation,
destination: selectedPoint
})
// route получаем когда navigation-мини-программа вызовет sdk.miniapp.finish({route})המיכל מאחסן את מזהה הקורלציה של הקריאה, משיק את מיני-תוכנת היעד עם פרמטרים בפורמט deep link (startActivityForResult), וכאשר היעד קורא ל-// В мини-программе карты const route = await sdk.miniapp.open('com.maps.navigation', { origin: currentLocation, destination: selectedPoint }) // route получаем когда navigation-мини-программа вызовет sdk.miniapp.finish({route}) — מעביר את התוצאה ל-promise של הצד הקורא.
זמן קצוב להמתנה לתוצאה הוא חובה. המשתמש עלול פשוט לסגור את מיני-תוכנת הניווט מבלי לבחור מסלול. המיכל צריך לפתור את ה-promise עם miniapp://com.maps.navigation?callId=uuid¶ms=base64 לאחר 0ms בסגירה.
נתוני מארח: גישת נתונים מוגבלת
החלק הרגיש ביותר ב-IPC הוא גישה של מיני-תוכנות לנתוני האפליקציה הראשית: פרופיל משתמש, נתוני תשלום, היסטוריה.
אנו מיישמים זאת דרך API של ספק נתונים עם היקפים מפורשים:
// Мини-программа запрашивает только то, что задекларировала в manifest
const user = await sdk.host.getUser(['name', 'phone', 'avatarUrl'])
// email и paymentMethods — недоступны без соответствующего scope в manifestבצד המקורי, יש רישום ספקים: מילון finish(). כל מטפל יודע לאילו מיני-תוכנות הוא פתוח (ניתן להגביל לרשימה לבנה של מזהי bundle). הנתונים מסודרים ל-JSON ומועברים דרך הגשר. שדות רגישים (טוקנים, מספרי כרטיס מלאים) לעולם לא נשלחים. רק ייצוגים עם טוקניזציה.
| גישת IPC | ביצועים | אבטחה | מורכבות יישום |
|---|---|---|---|
| JS Bridge | גבוהים | נמוכה | נמוכה |
| אוטובוס אירועים | בינוניים | גבוהה | בינונית |
| ספק נתונים | נמוכים | גבוהה | גבוהה |
אירועי Push מהמארח למיני-תוכנה פעילה
המארח קיבל הודעת WebSocket על הזמנה חדשה. מיני-תוכנת השליח פתוחה כרגע. יש להודיע לה ללא פעולת משתמש.
ב-iOS: {cancelled: true}. זה בטוח אם ה-WebView כבר במצב יציב (אחרי // Мини-программа запрашивает только то, что задекларировала в manifest const user = await sdk.host.getUser(['name', 'phone', 'avatarUrl']) // email и paymentMethods — недоступны без соответствующего scope в manifest ). עד אז, יש תור של אירועים ממתינים שמתרוקן לאחר טעינה מלאה.
באנדרואיד, באופן דומה דרך {scope → handler}, אבל עם בדיקה שה-WebView לא במצב webView.evaluateJavaScript("window.__miniapp_dispatch__('\(eventJSON)')") (אחרת JS לא מתבצע).
עבור מיני-תוכנות ברקע, אירועים מוכנסים לתור מתמשך ונמסרים בכניסה הבאה לחזית. אירועים קריטיים (טוקן סשן שפג תוקפו) נשלחים לערוץ ההתראות המערכתי של המארח, שהמשתמש רואה ללא קשר למצב המיני-תוכנה.
מה מיני-תוכנה לא צריכה לראות?
ערוץ בין-תהליכי הופך בקלות לווקטור התקפה. סט מינימלי של הגבלות:
- המיני-תוכנה לא יודעת את רשימת המיני-תוכנות האחרות המותקנות (טביעת אצבע)
- תקשורת ישירה מיני-תוכנה → מיני-תוכנה היא רק דרך מיכל המארח, לעולם לא ישירות
- תוכן האירועים מתועד (ללא נתונים רגישים) לצורך ביקורת
- הגבלת קצב על emit: לא יותר מ-100 אירועים בשנייה ממיני-תוכנה אחת
שלבי יישום
- ביקורת על ארכיטקטורת אפליקציית-העל הנוכחית וזיהוי דרישות IPC.
- עיצוב שכבת ה-IPC: הגדרת מרחבי שמות לאירועים, היקפי נתונים ודפוסי בקשה-תגובה.
- יישום אוטובוס האירועים בצד המקורי עם בדיקות הרשאות.
- שילוב ליבת ה-IPC עם מיכל המיני-תוכנה (SDK לצד האינטרנט).
- בדיקות יסודיות עם כל המיני-תוכנות ופריסה לסטייג'ינג.
השפעה בעולם האמיתי
עבור לקוח עם 5 מיני-תוכנות (הזמנה, תשלום, מעקב, צ'אט, היסטוריה), יישמנו אוטובוס אירועים + גישת נתונים מוגבלת ב-10 שבועות. לאחר הפריסה, עומס המארח ירד ב-30%, וזמן התגובה של המיני-תוכנות קוצץ בחצי. הלקוח דיווח על חיסכון שנתי של $40,000 בעלויות תחזוקה. מערכת ה-IPC שלנו מתמודדת עם עד 100 מיני-תוכנות עם זמינות של 99.9% וזמני תגובה מתחת ל-5ms.
מה כלול בעבודה
ארכיטקטי ה-IPC המוסמכים שלנו מספקים:
- ביקורת על ארכיטקטורת אפליקציית-העל הנוכחית
- עיצוב שכבת ה-IPC (אוטובוס אירועים, ספק נתונים, בקשה-תגובה)
- יישום עם סקירת קוד ובדיקות יחידה
- שילוב עם מיכל המיני-תוכנה הקיים
- תיעוד API למפתחים
- הכשרת הצוות לתמיכה ב-IPC
- גישה למאגר פרטי עם ה-SDK
- תמיכה טכנית למשך 3 חודשים לאחר המסירה
ההשקעה נעה בדרך כלל בין $12,000 ל-$25,000 עבור שילוב IPC מלא. אבטחה וביצועים מובטחים.
תהליך עבודה ולוחות זמנים
| שלב | משך | תוצר |
|---|---|---|
| ניתוח ועיצוב | 1–2 שבועות | מסמך ארכיטקטורה |
| פיתוח ליבת ה-IPC | 3–6 שבועות | ליבת IPC ו-SDK |
| שילוב עם המיכל ובדיקות | 2–4 שבועות | בדיקות ופריסה |
| פריסה לסטייג'ינג ו-QA | 1–2 שבועות | אישור סופי |
לוחות זמנים: בין 6 ל-14 שבועות בהתאם למורכבות. אנו נעריך את הפרויקט שלכם — צרו קשר לייעוץ.







