‏הצגת רשומות עם תוויות PeerChannel. הצג את כל הרשומות
‏הצגת רשומות עם תוויות PeerChannel. הצג את כל הרשומות

יום ראשון, 13 בפברואר 2011

Scalable state synchronization using P2P - part 3 – איך להשתמש בתשתית באפליקציה שלך

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

 

אם לא מעוניינים ב NuGet אפשר ישר לקפוץ לשלב הבא "הוספה ידנית – ללא NuGet"

התקנה באמצעות NuGet

אני מתבסס על זה שכבר יודעים מה זה NuGet , אם בכל זאת לא מכירים אפשר לקרוא כאן ובעברית

Add Library Package reference:
Add library package reference

חיפוש והתקנה של החבילה P2PSync
Add library package reference dialog
Add library package reference dialog - licence

לאחר שהחבילה הותקנה נוספים לפרויקט מספר assemblies וכמו כן קובץ app.config מתעדכן (או נוצר אם לא היה קודם)
P2PSync - package installed

ה assemblies:
(dependencies for NLog)
NLog.dll
NLog.Extended.dll – הקובץ הזה איננו חובה וניתן להוריד אותו , במיוחד באפליקציות עם .Net client profile – שאז הוא לא מתאים.
Roniz.Diagnostics.Logging.dll - מעטפת שלי ל NLog
כל ה assemblies הללו כדי לתמוך ב Logging , אני משתמש ב Log2Console , ניתן להוריד מ codeplex.
וה assemblies העיקריים של התשתית:
Roniz.WCF.P2P.Channels.dll
Roniz.WCF.P2P.Messages.dll
Roniz.WCF.P2P.Sync.dll
Roniz.Diagnostics.Logging.dll

הוספה ידנית – ללא NuGet

במידה ולא רוצים להשתמש ב NuGet צריך להוריד את הגרסה האחרונה מ codeplex.
ולהוסיף את הקבצים הבאים לפרויקט:

Roniz.Diagnostics.Logging.dll
Roniz.WCF.P2P.Channels.dll
Roniz.WCF.P2P.Messages.dll

בנוסף להוריד מ NLog ולהוסיף את הקבצים הבאים:
NLog.dll

מימוש ה business logic הספציפי של הפרויקט

המימוש נעשה ע"י ירושה מRoniz.WCF.P2P.Sync.Interfaces.ISynchronizationBusinessLogic - באפליקציה לדוגמא זה ה Roniz.WCF.P2P.ApplicationTester.MySynchronizationBusinessLogic

מימוש הודעות בין ה peers:

FullPresenceInfo מכיל את הנתונים שישלחו מה peer לשאר ה peers כשהסטטוס שלו נהפך ל Online , באפליקציה לדוגמא זה ה Roniz.WCF.P2P.ApplicationTester.Messages.MyFullPresenceInfo class.
CompactPresenceInfo - מכיל את הנתונים שישלחו מה peer לשאר ה peers כשקוראים ל close ב manager – זה המקום שה peers האחרים יכולים לדעת ש peer מסוים ירד ולפעול בהתאם , באפליקציה לדוגמא Roniz.WCF.P2P.ApplicationTester.Messages.MyCompactPresenceInfo.
BusinessLogicMessageBase – ה base class שמשמש את כל ההודעות ה business logics האחרות (למשל הודעות עדכונים).

שימוש בקוד (הקוד מהאפליקציה לדוגמא):
אתחול synchronization manager:
כשמאתחלים את SynchronizationStateManager צריך לספק לו את הclass שמממש את ה businesslogic:
SyncManager = new SynchronizationStateManager(MySynchronizationBusinessLogic);

וכשרוצים להתחיל לסנכרן:
SyncManager.Open();

שליחת נתונים לאחר הסנכרון הראשוני
במהלך הריצה של האפליקציה בדרך כלל יש צורך בשליחת עדכונים לשאר ה הpeers , ניתן לעשות זאת באמצעות Update

לדוגמא:
var updateState = new MyStateContainer
{
  StateDictionary = new Dictionary<Guid, MyUserUpdateState>(1)
};
updateState.StateDictionary.Add(id, UserState);
SyncManager.Update(updateState);

הפסקת סנכרון – סגירת ה manager:
הודעה לשאר ה peer שה peer הנוכחי יורד
SyncManager.Close();

יום רביעי, 2 בפברואר 2011

Scalable state synchronization using P2P

בהרבה אפליקציות שמפתחים נדרש לשתף נתונים בין ה server ל client וגם בין מספר clients ל server אחד.

ככל שמספר ה clients גודל – כך העומס על השרת עולה , Azure פותר אולי את הבעיה ברמה הטכנית , אבל יש צורך לשלם על זה...

עם הזמן שמתי לב שיש דפוס כמעט קבוע שחוזר על עצמו בהרבה אפליקציות:

כשה client עולה הוא מסתנכרן מול ה server , וכך כל client נוסף שעולה חוזר על הפעולה.

כשיש שינוי באחד מה clients הוא מעדכן את ה server ומשם יש שתי אופציות:

1. או שה clients עושים pooling ל server כדי לקבל עדכונים.

2. או שה server שולח הודעה (למשל ב WCF ע"י מימוש Pub/Sub) לשאר ה clients.

לכאורה הפתרון השני הוא המועדף – אבל יש איתו מספר בעיות:

1. אם ה clients נמצאים מאחורי NAT או Firewall שמונע מה server שליחת הודעות ב callback אליהם , חייבים להחזיק socket פתוח אל ה server , ואז ככל שכמות ה clients עולה – כך כמות ה sockets הפתוחים בצד ה server.

2. בכמויות גדולות של clients ה server צריך לשלוח את אותה הודעה לכולם מה שיוצר אצלו ג"כ צוואר בקבוק מבחינת ביצועים.

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

חלק מהרעיונות למדתי מ Kevin Hoffman שפירסם מאמר ב msdn magazine

בעיות קיימות (מקווה לפתור בגרסה נוספת):

1. זמן פתיחה ארוך של ה proxy , וזמן נוסף שעובר לאחר שנוסף peer ל mesh עד ל online event ולתחילת הסנכרון.

2. בסיטואציות מסויימות יכול להיות mesh אחד שמכיל מספר peers אבל מספר קבוצות של peers כך שכל peer חושב שהוא Online ומסונכרן עם כל ה mesh , אבל הסנכרון שלו הוא רק עם התת קבוצה שאליה הוא מחובר , הפיתרון כרגע מבוסס על refresh שנעשה ב interval שניתן לשלוט בו (default 30 שניות בכל peer)

הקוד עדיין בתחילת הדרך , אשמח לקבל הערות ושיפורים.

ניתן להוריד אותו מכאן.

הסבר על האפליקציה לדוגמא:

כל חלון מייצג peer אחד ב mesh , ויש לו name ו data שניתן לערוך:

clip_image001

א. לאחר שלוחצים על connect ה peer פותח channel וה communication status שלו עובר ל opening ולאחר מכן opened, ברגע שה peer עובר לסטטוס opened הוא מכניס ל grid את הפרטים שלו , ועדיין לא מסונכרן מול peerים אחרים.

בדוגמא peer A ו peer B עברו ל Opened והכניסו את המידע על עצמם – עדיין ללא סנכרון , peer C עדיין לא נפתח ונמצא בסטטוס created

clip_image002

ב. אם הוא מוצא peer נוסף הוא עובר לסטטוס online , ומתחיל תהליך סנכרון מול ה peerים האחרים – שולח להם בקשה לסנכרון , מקבל את המידע ומציג אותו ב grid , אותו דבר קורה ב peerים האחרים שעברו למצב online

בדוגמא A ו B במצב Online ומסונכרנים ביניהם

clip_image003

ג. לחיצה על send update of own details תעדכן את כל ה peers האחרים בנתונים שיש באיזור ה user details.

בדוגמא D מעדכן את A B ו C ב "some new data":

clip_image004

ד. לחיצה על disconnect תשלח הודעה ל peerים האחרים על יציאה – והם ינקו את השורה שמייצגת את ה peer שירד.

clip_image005