על לקוח האינטרנט של 1C

אחת התכונות הנחמדות של טכנולוגיית 1C:Enterprise היא שניתן להריץ פתרון יישומים שפותח באמצעות טכנולוגיית טפסים מנוהלים הן בלקוח רזה (ניתן להרצה) והן בלקוח... Windows, Linux, MacOS X, וכלקוח אינטרנט עבור חמישה דפדפנים - Chrome, Internet Explorer, Firefox, Safari ו-Edge - והכל מבלי לשנות את קוד המקור של היישום. יתר על כן, היישום מתפקד ונראה כמעט זהה גם בלקוח הרזה וגם בדפדפן.
מצא 10 הבדלים (2 תמונות מתחת לחיתוך):

חלון הלקוח הרזה מופעל Linux:

על לקוח האינטרנט של 1C

אותו חלון בלקוח האינטרנט (בדפדפן כרום):

על לקוח האינטרנט של 1C

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

על לקוח האינטרנט של 1C

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

הצהרת הבעיה

אז, הדרישות לפרויקט: לקוח האינטרנט צריך לעשות את אותו הדבר כמו הלקוח הרזה, כלומר:

  1. ממשק משתמש לתצוגה
  2. ביצוע קוד לקוח שנכתב בשפת 1C

ממשק המשתמש ב-1C מתואר בעורך חזותי, אך באופן הצהרתי, ללא סידור פיקסל אחר פיקסל של אלמנטים; נעשה שימוש בכשלושה תריסר סוגים של אלמנטי ממשק - כפתורים, שדות קלט (טקסט, דיגיטלי, תאריך/שעה), רשימות, טבלאות, גרפים וכו'.

קוד לקוח בשפת 1C יכול להכיל קריאות שרת, עבודה עם משאבים מקומיים (קבצים וכו'), הדפסה ועוד.

גם הלקוח הרזה (כאשר עובדים דרך האינטרנט) וגם לקוח האינטרנט משתמשים באותו סט של שירותי אינטרנט כדי לתקשר עם שרת היישומים 1C. המימוש של הלקוחות שונה, כמובן - הלקוח הרזה כתוב ב-C++, ולקוח האינטרנט - ב-JavaScript.

קצת היסטוריה

פרויקט לקוח האינטרנט החל בשנת 2006, עם צוות ממוצע של 5 אנשים. בשלבים מסוימים של הפרויקט, מפתחים גויסו כדי ליישם פונקציונליות ספציפית (מסמך טבלה, דיאגרמות וכו'); ככלל, אלה היו אותם מפתחים שביצעו פונקציונליות זו בלקוח הרזה. כלומר, המפתחים כתבו מחדש רכיבי JavaScript שיצרו בעבר ב-C++.

כבר מההתחלה, דחינו את הרעיון של כל המרה אוטומטית (אפילו חלקית) של קוד ++C של לקוח רזה ל-JavaScript של לקוח אינטרנט עקב ההבדלים הקונספטואליים החזקים בין שתי השפות; לקוח האינטרנט נכתב ב-JavaScript מאפס.

באיטרציות הראשונות של הפרויקט, לקוח האינטרנט המיר את קוד הלקוח בשפת 1C המובנית ישירות ל-JavaScript. הלקוח הרזה עושה זאת אחרת - הקוד בשפת 1C המובנית עובר קומפילציה לקוד בייט, ולאחר מכן קוד בייט זה מתפרש על הלקוח. לאחר מכן, לקוח האינטרנט החל לעשות את אותו הדבר - ראשית, זה נתן שיפור בביצועים, ושנית, זה אפשר לאחד את הארכיטקטורה של הלקוחות הרזה והאינטרנט.

הגרסה הראשונה של פלטפורמת 1C:Enterprise עם תמיכה בלקוח אינטרנט שוחררה בשנת 2009. באותה תקופה, לקוח האינטרנט תמך בשני דפדפנים - אינטרנט אקספלורר ופיירפוקס. התוכניות הראשוניות כללו תמיכה באופרה, אך עקב בעיות בלתי פתירות עם מטפלי סגירת האפליקציות באופרה (לא ניתן היה לעקוב בוודאות של 2% שהאפליקציה נסגרת, ובאותו רגע לבצע את הליך הניתוק משרת האפליקציות של 100C), נאלצו תוכניות אלו להיזנח.

מבנה הפרויקט

בסך הכל, לפלטפורמת 1C:Enterprise יש 4 פרויקטים שנכתבו ב-JavaScript:

  1. WebTools – ספריות נפוצות המשמשות פרויקטים אחרים (אנו כוללים גם כאן ספריית הסגירה של גוגל).
  2. רכיב בקרה מסמך מעוצב (מיושמת ב-JavaScript הן בלקוח הרזה והן בלקוח האינטרנט)
  3. רכיב בקרה מתזמן (מיושמת ב-JavaScript הן בלקוח הרזה והן בלקוח האינטרנט)
  4. לקוח אינטרנט

המבנה של כל פרויקט דומה למבנה של פרויקטי Java (או פרויקטי .NET - הקרובים אליך מביניהם); יש לנו מרחבי שמות, וכל מרחב שמות נמצא בתיקייה נפרדת. בתוך התיקייה נמצאים קבצי מרחב השמות והמחלקות. לפרויקט לקוח האינטרנט יש כ-1000 קבצים.

מבחינה מבנית, לקוח האינטרנט מחולק באופן כללי לתת-המערכות הבאות:

  • ממשק יישום לקוח מנוהל
    • ממשק יישום כללי (תפריטי מערכת, פאנלים)
    • ממשק הטפסים הנשלטים, הכולל, בין היתר, כ-30 רכיבי בקרה (כפתורים, סוגים שונים של שדות קלט - טקסט, דיגיטלי, תאריך/שעה וכו', טבלאות, רשימות, גרפים וכו')

  • מודל אובייקטים זמין למפתחים במערכת הלקוח (מעל 400 סוגים בסך הכל: מודל אובייקטים של הממשק המנוהל, הגדרות פריסת נתונים, עיצוב מותנה וכו')
  • מתורגמן של השפה המובנית 1C
  • הרחבות דפדפן (משמשות לפונקציונליות שאינה נתמכת על ידי JavaScript)
    • עבודה עם קריפטוגרפיה
    • עבודה עם קבצים
    • טכנולוגיית רכיבים חיצוניים המאפשרת שימוש בהם הן בלקוחות דקים והן בלקוחות אינטרנטיים

מאפייני פיתוח

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

כדי למזער את גודל קוד הלקוח, השתמשנו בתחילה ב-obfuscator משלנו, והחל מגרסת הפלטפורמה 8.3.6 (אוקטובר 2014) התחלנו להשתמש מהדר הסגירות של גוגלהשפעת השימוש במספרים - גודל מסגרת לקוח האינטרנט לאחר ערפול:

  • ערפל משלו - 1556 קילו-בייט
  • מהדר סגירות גוגל – 1073 קילו-בייט

השימוש ב-Google Closure Compiler עזר לנו לשפר את ביצועי לקוח האינטרנט ב-30% בהשוואה לערפל שלנו. בנוסף, כמות הזיכרון שנצרכה על ידי האפליקציה ירדה ב-15-25% (בהתאם לדפדפן).

Google Closure Compiler עובד מצוין עם קוד מונחה עצמים, כך שהיעילות שלו היא הגבוהה ביותר עבור לקוח האינטרנט. Closure Compiler עושה כמה דברים טובים עבורנו:

  • בדיקת טיפוס סטטית בשלב בניית הפרויקט (מובטחת על ידי העובדה שאנו מכסים את הקוד עם הערות JSDoc). התוצאה היא הקלדה סטטית, קרובה מאוד ברמה להקלדה ב-C++. זה עוזר לתפוס אחוז גדול למדי של שגיאות בשלב קומפילציית הפרויקט.
  • צמצום גודל הקוד באמצעות ערפול
  • מספר אופטימיזציות לקוד הניתן להרצה, כגון:
    • החלפות פונקציות מוטבעות. קריאה לפונקציה ב-JavaScript היא פעולה יקרה למדי, והחלפות מוטבעות של מתודות קטנות הנמצאות בשימוש תכוף מאיצות משמעותית את הקוד.
    • חישוב קבוע זמן קומפילציה. אם ביטוי תלוי בקבוע, הערך בפועל של הקבוע יוכנס לתוכו.

אנו משתמשים ב-WebStorm כסביבת פיתוח לקוח אינטרנט שלנו.

כדי לנתח את הקוד בו אנו משתמשים soundQube, שם אנו משלבים מנתחי קוד סטטי. בעזרת מנתחים, אנו עוקבים אחר הירידה באיכות קוד המקור של JavaScript ומנסים למנוע אותה.

על לקוח האינטרנט של 1C

אילו בעיות פתרנו/אנחנו פותרים?

במהלך ביצוע הפרויקט נתקלנו במספר בעיות מעניינות שהיינו צריכים לפתור.

חילופי נתונים עם השרת ובין חלונות

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

  • קוד המגיע מהשרת בצורה של מבני נתונים
  • קוד של חלון יישום אחר

כדי למנוע ערפול בעת אינטראקציה עם השרת, אנו משתמשים בתג @expose:

/**
 * @constructor
 * @extends {Base.SrvObject}
 */
Srv.Core.GenericException = function ()
{
    /**
     * @type {string}
     * @expose
     */
    this.descr;

    /**
     * @type {Srv.Core.GenericException}
     * @expose
     */
    this.inner;

    /**
     * @type {string}
     * @expose
     */
    this.clsid;

    /**
     * @type {boolean}
     * @expose
     */
    this.encoded;
}

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

/**
 * Экспортируемый интерфейс контрола DropDownWindow
 *
 * @interface
 * @struct
 */
WebUI.IDropDownWindowExp = function(){}

/**
 * Перемещает выделение на 1 вперед или назад
 *
 * @param {boolean} isForward
 * @param {boolean} checkOnly
 * @return {boolean}
 * @expose
 */
WebUI.IDropDownWindowExp.prototype.moveMarker = function (isForward, checkOnly){}

/**
 * Перемещает выделение в начало или конец
 *
 * @param {boolean} isFirst
 * @param {boolean} checkOnly
 * @return {boolean}
 * @expose
 */
WebUI.IDropDownWindowExp.prototype.moveMarkerTo = function (isFirst, checkOnly){}

/**
 * @return {boolean}
 * @expose
 */
WebUI.IDropDownWindowExp.prototype.selectValue = function (){}

השתמשנו ב-Virtual DOM לפני שזה הפך למיינסטרים)

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

אופטימיזציה של לקוח האינטרנט

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

על לקוח האינטרנט של 1C

בדיקה

עבור בדיקות פונקציונליות וביצועים, אנו משתמשים בכלי שיצרנו בעצמנו (נכתב ב-Java ו-C++) ובמערכת בדיקות שנבנתה על גבי סלניום.

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

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

על לקוח האינטרנט של 1C
כלי הבדיקה שלנו והאפליקציה הנבדקת

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

בדיקות בשני הכלים (שלנו וסלניום) מריצות תרחישי עבודה אופייניים מפתרונות היישומים שלנו. הבדיקות מופעלות אוטומטית לאחר הבנייה היומית של פלטפורמת 1C:Enterprise. אם עבודת התרחישים מואטת (בהשוואה לבנייה הקודמת), אנו עורכים חקירה ומבטלים את הגורם להאטה. הקריטריון שלנו פשוט - הבנייה החדשה לא צריכה לעבוד לאט יותר מהקודמת.

כדי לחקור אירועי האטה, מפתחים משתמשים בכלים שונים; הנפוץ ביותר הוא מהדורת AJAX של Dynatrace הייצור של החברה דינאטרייסיומני ביצוע הפעולה הבעייתי נרשמים בגירסאות קודמות וחדשות, ולאחר מכן מנותחים הלוגים. במקרה זה, זמן הביצוע של פעולות בודדות (באלפיות שנייה) לא בהכרח מהווה גורם מכריע - תהליכי שירות כגון איסוף זבל מופעלים מעת לעת בדפדפן, הם יכולים לחפוף עם זמן הביצוע של פונקציות ולעוות את התמונה. פרמטרים רלוונטיים יותר במקרה זה יהיו מספר הוראות ה-JavaScript שבוצעו, מספר הפעולות האטומיות ב-DOM וכו'. אם מספר ההוראות/פעולות באותו סקריפט גדל בגרסה החדשה, זה כמעט תמיד אומר ירידה בביצועים שיש לתקן.

סיבה נוספת לירידה בביצועים עשויה להיות ש-Google Closure Compiler, מסיבה כלשהי, לא הצליח להטמיע את הפונקציה (לדוגמה, מכיוון שהפונקציה היא רקורסיבית או וירטואלית). במקרה זה, אנו מנסים לתקן את המצב על ידי כתיבה מחדש של קוד המקור.

הרחבות דפדפן

במקרים בהם פתרון יישום דורש פונקציונליות שאינה זמינה ב-JavaScript, אנו משתמשים בהרחבות דפדפן:

התוספים שלנו מורכבים משני חלקים. החלק הראשון הוא מה שנקרא הרחבת דפדפן (בדרך כלל הרחבת JavaScript עבור Chrome ו-Firefox), אשר מקיים אינטראקציה עם החלק השני - הרחבה בינארית שמיישמת את הפונקציונליות שאנו צריכים. ראוי לציין שאנו כותבים שלוש גרסאות של הרחבות בינאריות - אחת לכל אחת. Windows, Linux ו-MacOS. התוסף הבינארי כלול בפלטפורמת 1C:Enterprise ונמצא בשרת היישומים של 1C. כאשר ניגשים אליו לראשונה מלקוח האינטרנט, הוא מוריד למחשב הלקוח ומותקן בדפדפן.

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

פיתוח עתידי

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

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

מקור: www.habr.com

קנה אירוח אמין לאתרים עם הגנת DDoS, שרתי VPS VDS 🔥 קנה אחסון אתרים אמין עם הגנת DDoS, שרתי VPS VDS | ProHoster