Rreth klientit të internetit 1C

Një nga veçoritë e këndshme të teknologjisë 1C: Enterprise është se zgjidhja e aplikacionit, e zhvilluar duke përdorur teknologjinë e formave të menaxhuara, mund të lëshohet si në një klient të hollë (të ekzekutueshëm) për Windows, Linux, MacOS X dhe si një klient në internet për 5 shfletues - Chrome, Internet Explorer, Firefox, Safari, Edge dhe e gjithë kjo pa ndryshuar kodin burimor të aplikacionit. Për më tepër, nga jashtë aplikacioni në thin client dhe në shfletues funksionon dhe duket pothuajse identik.
Gjeni 10 dallime (2 fotografi nën prerje):

Dritarja e hollë e klientit në Linux:

Rreth klientit të internetit 1C

E njëjta dritare në klientin në internet (në shfletuesin Chrome):

Rreth klientit të internetit 1C

Pse krijuam një klient në internet? E thënë disi patetikisht, koha na ka vendosur një detyrë të tillë. Puna në internet ka qenë prej kohësh një parakusht për aplikimet e biznesit. Së pari, ne shtuam mundësinë për të punuar përmes Internetit për klientin tonë të hollë (disa nga konkurrentët tanë, meqë ra fjala, u ndalën atje; të tjerët, përkundrazi, braktisën klientin e hollë dhe u kufizuan në zbatimin e një klienti në internet). Ne vendosëm t'u japim përdoruesve tanë mundësinë për të zgjedhur opsionin e klientit që u përshtatet më shumë.

Rreth klientit të internetit 1C

Shtimi i aftësive të bazuara në ueb tek klienti i hollë ishte një projekt i madh me një ndryshim të plotë në arkitekturën klient-server. Krijimi i një klienti në internet është një projekt krejtësisht i ri, duke filluar nga e para.

Formulimi i problemit

Pra, kërkesat e projektit: klienti në internet duhet të bëjë të njëjtën gjë si klienti i hollë, përkatësisht:

  1. Shfaq ndërfaqen e përdoruesit
  2. Ekzekutoni kodin e klientit të shkruar në gjuhën 1C

Ndërfaqja e përdoruesit në 1C përshkruhet në një redaktues vizual, por në mënyrë deklarative, pa rregullim piksel pas piksel të elementeve; Përdoren rreth tre duzina lloje të elementeve të ndërfaqes - butona, fusha hyrëse (tekst, numerikë, datë/ora), lista, tabela, grafikë, etj.

Kodi i klientit në gjuhën 1C mund të përmbajë thirrje serveri, punë me burime lokale (skedarë, etj.), printim dhe shumë më tepër.

Si klienti i hollë (kur punoni përmes ueb-it) dhe klienti i uebit përdorin të njëjtin grup shërbimesh në internet për të komunikuar me serverin e aplikacionit 1C. Implementimet e klientit, natyrisht, janë të ndryshme - klienti i hollë është shkruar në C++, klienti i uebit është shkruar në JavaScript.

Pak histori

Projekti i klientit në internet filloi në vitin 2006, me një ekip prej (mesatarisht) 5 personash. Në faza të caktuara të projektit, zhvilluesit u përfshinë për të zbatuar funksione specifike (dokument i fletëllogaritjes, diagrame, etj.); si rregull, këta ishin të njëjtët zhvillues që e bënë këtë funksion në klientin e hollë. Ato. zhvilluesit rishkruan komponentët në JavaScript që i kishin krijuar më parë në C++.

Që nga fillimi, ne hodhëm poshtë idenë e çdo konvertimi automatik (madje edhe të pjesshëm) të kodit të klientit të hollë C++ në klient web JavaScript për shkak të dallimeve të forta konceptuale midis dy gjuhëve; klienti i uebit është shkruar në JavaScript nga e para.

Në përsëritjet e para të projektit, klienti i uebit konvertoi kodin e klientit në gjuhën e integruar 1C direkt në JavaScript. Klienti i hollë vepron ndryshe - kodi në gjuhën e integruar 1C përpilohet në bytecode, dhe më pas ky bajtkod interpretohet në klient. Më pas, klienti i uebit filloi të bëjë të njëjtën gjë - së pari, ai dha një rritje të performancës dhe së dyti, bëri të mundur unifikimin e arkitekturës së klientëve të hollë dhe të uebit.

Versioni i parë i platformës 1C: Enterprise me mbështetjen e klientit në internet u lëshua në 2009. Klienti i uebit në atë kohë mbështeti 2 shfletues - Internet Explorer dhe Firefox. Planet fillestare përfshinin mbështetje për Opera, por për shkak të problemeve të pakapërcyeshme në atë kohë me mbajtësit e mbylljes së aplikacionit në Opera (nuk ishte e mundur të gjurmohej me siguri 100% që aplikacioni po mbyllej dhe në atë moment të kryhej procedura e shkëputjes nga serveri i aplikacionit 1C) nga këto plane duhej të braktisej.

Struktura e projektit

Në total, platforma 1C:Enterprise ka 4 projekte të shkruara në JavaScript:

  1. WebTools – biblioteka të përbashkëta të përdorura nga projekte të tjera (ne përfshijmë gjithashtu Biblioteka e mbylljes së Google).
  2. Elementi i kontrollit Dokument i Formatuar (i implementuar në JavaScript si në klientin e hollë ashtu edhe në klientin në ueb)
  3. Elementi i kontrollit Programuesi (i implementuar në JavaScript si në klientin e hollë ashtu edhe në klientin në ueb)
  4. Klient në ueb

Struktura e çdo projekti i ngjan strukturës së projekteve Java (ose projekteve .NET - cilado që është më afër); Ne kemi hapësira emrash, dhe secila hapësirë ​​e emrave është në një dosje të veçantë. Brenda dosjes ka skedarë dhe klasa të hapësirës së emrave. Ka rreth 1000 skedarë në projektin e klientit në internet.

Strukturisht, klienti në internet është i ndarë kryesisht në nënsistemet e mëposhtme:

  • Ndërfaqja e menaxhuar e aplikacionit të klientit
    • Ndërfaqja e përgjithshme e aplikacionit (menytë e sistemit, panelet)
    • Ndërfaqja e formave të menaxhuara, duke përfshirë, ndër të tjera, rreth 30 kontrolle (butona, lloje të ndryshme fushash hyrëse - tekst, numerikë, datë/ora, etj., tabela, lista, grafikë, etj.)

  • Modeli i objektit i disponueshëm për zhvilluesit në klient (mbi 400 lloje në total: modeli i objektit të ndërfaqes së menaxhuar, cilësimet e paraqitjes së të dhënave, stilimi i kushtëzuar, etj.)
  • Përkthyes i gjuhës së integruar 1C
  • Shtesat e shfletuesit (përdoret për funksionalitet që nuk mbështetet në JavaScript)
    • Puna me kriptografi
    • Puna me skedarë
    • Teknologji e komponentëve të jashtëm, duke i lejuar ato të përdoren si në klientët e hollë ashtu edhe në ueb

Karakteristikat e zhvillimit

Zbatimi i të gjitha sa më sipër në JavaScript nuk është i lehtë. Ndoshta klienti i uebit 1C është një nga aplikacionet më të mëdha të klientit të shkruar në JavaScript - rreth 450.000 rreshta. Ne përdorim në mënyrë aktive një qasje të orientuar nga objekti në kodin e klientit në internet, i cili thjeshton punën me një projekt kaq të madh.

Për të minimizuar madhësinë e kodit të klientit, ne fillimisht përdorëm obfuscatorin tonë dhe duke filluar me versionin e platformës 8.3.6 (tetor 2014) filluam të përdorim Përpiluesi i mbylljes së Google. Efekti i përdorimit në numra - madhësia e kornizës së klientit në internet pas errësimit:

  • Ngacmuesi i vet – 1556 kb
  • Përpiluesi i mbylljes së Google – 1073 kb

Përdorimi i Përpiluesit të Mbylljes së Google na ndihmoi të përmirësojmë performancën e klientit të uebit me 30% në krahasim me obfuscatorin tonë. Përveç kësaj, sasia e memories së konsumuar nga aplikacioni është ulur me 15-25% (në varësi të shfletuesit).

Përpiluesi i mbylljes së Google funksionon shumë mirë me kodin e orientuar nga objekti, kështu që efikasiteti i tij për klientin në ueb është sa më i lartë që të jetë e mundur. Përpiluesi i mbylljes bën disa gjëra të mira për ne:

  • Kontrollimi i tipit statik në fazën e ndërtimit të projektit (siguron që ne e mbulojmë kodin me shënime JSDoc). Rezultati është shtypja statike, shumë afër në nivel me shtypjen në C++. Kjo ndihmon për të kapur një përqindje mjaft të madhe gabimesh në fazën e përpilimit të projektit.
  • Zvogëlimi i madhësisë së kodit përmes turbullimit
  • Një numër optimizimesh të kodit të ekzekutuar, për shembull, si:
    • zëvendësimet e funksioneve inline. Thirrja e një funksioni në JavaScript është një operacion mjaft i kushtueshëm dhe zëvendësimet inline të metodave të vogla të përdorura shpesh përshpejtojnë ndjeshëm kodin.
    • Numërimi i konstantave në kohën e përpilimit. Nëse një shprehje varet nga një konstante, vlera aktuale e konstantës do të zëvendësohet në të

Ne përdorim WebStorm si mjedisin tonë të zhvillimit të klientit të internetit.

Për analizën e kodit ne përdorim soundQube, ku ne integrojmë analizues të kodit statik. Duke përdorur analizues, ne monitorojmë degradimin e cilësisë së kodit burimor JavaScript dhe përpiqemi ta parandalojmë atë.

Rreth klientit të internetit 1C

Çfarë problemesh kemi/po zgjidhim?

Gjatë zbatimit të projektit kemi hasur në një sërë problemesh interesante që na është dashur t'i zgjidhim.

Shkëmbeni të dhënat me serverin dhe midis dritareve

Ka situata ku turbullimi i kodit burimor mund të ndërhyjë në funksionimin e sistemit. Kodi i jashtëm i kodit të ekzekutueshëm të klientit të internetit, për shkak të turbullimit, mund të ketë emra funksionesh dhe parametrash që ndryshojnë nga ato që pret kodi ynë i ekzekutueshëm. Kodi i jashtëm për ne është:

  • Kodi që vjen nga serveri në formën e strukturave të të dhënave
  • Kodi për një dritare tjetër aplikacioni

Për të shmangur turbullimin kur ndërveprojmë me serverin, ne përdorim etiketën @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;
}

Dhe për të shmangur turbullimin kur ndërveprojmë me dritare të tjera, ne përdorim të ashtuquajturat ndërfaqe të eksportuara (ndërfaqe në të cilat eksportohen të gjitha metodat).

/**
 * Экспортируемый интерфейс контрола 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 (){}

Ne përdorëm Virtual DOM përpara se të bëhej i zakonshëm)

Ashtu si të gjithë zhvilluesit që merren me ndërfaqe të ndërlikuara të ueb-it, ne kuptuam shpejt se DOM nuk është i përshtatshëm për të punuar me ndërfaqet dinamike të përdoruesit. Pothuajse menjëherë, një analog i Virtual DOM u zbatua për të optimizuar punën me UI. Gjatë përpunimit të ngjarjeve, të gjitha ndryshimet DOM ruhen në memorie dhe, vetëm kur të gjitha operacionet të përfundojnë, ndryshimet e grumbulluara aplikohen në pemën DOM.

Optimizimi i klientit të internetit

Për ta bërë klientin tonë të internetit të funksionojë më shpejt, ne përpiqemi të përdorim në maksimum aftësitë standarde të shfletuesit (CSS, etj.). Kështu, paneli i komandës së formularit (i vendosur pothuajse në çdo formë të aplikacionit) jepet ekskluzivisht duke përdorur mjetet e shfletuesit, duke përdorur paraqitjen dinamike të bazuar në CSS.

Rreth klientit të internetit 1C

Testimi

Për testimin funksional dhe të performancës, ne përdorim një mjet të pronarit (të shkruar në Java dhe C++), si dhe një grup testesh të ndërtuara në krye të Selen.

Mjeti ynë është universal - ju lejon të testoni pothuajse çdo program me dritare, dhe për këtë arsye është i përshtatshëm për testimin e një klienti të hollë dhe një klient në internet. Mjeti regjistron veprimet e përdoruesit që nisi zgjidhjen e aplikacionit 1C në një skedar skripti. Në të njëjtën kohë, regjistrohen imazhe të zonës së punës të ekranit - standarde. Kur monitoroni versionet e reja të klientit në internet, skriptet luhen pa pjesëmarrjen e përdoruesit. Në rastet kur pamja e ekranit nuk përputhet me atë të referencës në asnjë hap, testi konsiderohet i dështuar, pas së cilës një specialist i cilësisë kryen një hetim për të përcaktuar nëse ky është një gabim apo një ndryshim i planifikuar në sjelljen e sistemit. Në rast të sjelljes së planifikuar, standardet zëvendësohen automatikisht me të reja.

Mjeti mat gjithashtu performancën e aplikacionit me një saktësi deri në 25 milisekonda. Në disa raste, ne lakojmë pjesë të skriptit (për shembull, duke përsëritur hyrjen e porosisë disa herë) për të analizuar degradimin e kohës së ekzekutimit me kalimin e kohës. Rezultatet e të gjitha matjeve regjistrohen në një regjistër për analizë.

Rreth klientit të internetit 1C
Mjeti ynë i testimit dhe aplikacioni në provë

Mjeti ynë dhe Seleni plotësojnë njëri-tjetrin; për shembull, nëse ndonjë buton në një nga ekranet ka ndryshuar vendndodhjen e tij, Selenium mund të mos e gjurmojë këtë, por mjeti ynë do ta vërejë, sepse bën një krahasim pixel për pixel të pamjes së ekranit me standardin. Mjeti është gjithashtu në gjendje të gjurmojë problemet me përpunimin e të dhënave nga tastiera ose miu, pasi kjo është pikërisht ajo që riprodhon.

Testet në të dy mjetet (tona dhe Selenium) kryejnë skenarë tipikë pune nga zgjidhjet tona të aplikimit. Testet nisen automatikisht pas ndërtimit të përditshëm të platformës 1C:Enterprise. Nëse skriptet janë më të ngadalta (krahasuar me versionin e mëparshëm), ne hetojmë dhe zgjidhim shkakun e ngadalësimit. Kriteri ynë është i thjeshtë - ndërtimi i ri nuk duhet të funksionojë më ngadalë se ai i mëparshmi.

Zhvilluesit përdorin mjete të ndryshme për të hetuar incidentet e ngadalësimit; përdoret kryesisht Dynatrace AJAX Edition kompani prodhuese DynaTrace. Regjistrohen regjistrat e ekzekutimit të operacionit problematik në ndërtimet e mëparshme dhe të reja, më pas analizohen regjistrat. Në të njëjtën kohë, koha e ekzekutimit të operacioneve të vetme (në milisekonda) mund të mos jetë një faktor vendimtar - proceset e shërbimit si mbledhja e mbeturinave lansohen periodikisht në shfletues, ato mund të mbivendosen me kohën e ekzekutimit të funksioneve dhe të shtrembërojnë figurën. Parametrat më të rëndësishëm në këtë rast do të ishin numri i instruksioneve JavaScript të ekzekutuara, numri i operacioneve atomike në DOM, etj. Nëse numri i udhëzimeve/operacioneve në të njëjtin skenar është rritur në një version të ri, kjo pothuajse gjithmonë nënkupton një rënie të performancës që duhet korrigjuar.

Gjithashtu, një nga arsyet e rënies së performancës mund të jetë se Google Closure Compiler për ndonjë arsye nuk ishte në gjendje të kryente zëvendësimin inline të funksionit (për shembull, sepse funksioni është rekurziv ose virtual). Në këtë rast, ne përpiqemi të korrigjojmë situatën duke rishkruar kodin burimor.

Shtesat e shfletuesit

Kur një zgjidhje aplikacioni ka nevojë për funksionalitet që nuk është i disponueshëm në JavaScript, ne përdorim shtesat e shfletuesit:

Shtesat tona përbëhen nga dy pjesë. Pjesa e parë është ajo që quhet zgjerim i shfletuesit (zakonisht shtesa për Chrome dhe Firefox të shkruara në JavaScript), të cilat ndërveprojnë me pjesën e dytë - një shtesë binare që zbaton funksionalitetin që na nevojitet. Duhet përmendur se ne shkruajmë 3 versione të shtesave binare - për Windows, Linux dhe MacOS. Shtesa binar ofrohet si pjesë e platformës 1C:Enterprise dhe ndodhet në serverin e aplikacionit 1C. Kur thirret për herë të parë nga një klient web, ai shkarkohet në kompjuterin e klientit dhe instalohet në shfletues.

Kur ekzekutohen në Safari, shtesat tona përdorin NPAPI; kur ekzekutohen në Internet Explorer, ato përdorin teknologjinë ActiveX. Microsoft Edge nuk mbështet ende shtesat, kështu që klienti i uebit në të funksionon me kufizime.

Zhvillimi i mëtutjeshëm

Një nga detyrat e ekipit të zhvillimit të klientit në internet është zhvillimi i mëtejshëm i funksionalitetit. Funksionaliteti i klientit të uebit duhet të jetë identik me funksionalitetin e klientit të hollë; i gjithë funksionaliteti i ri zbatohet njëkohësisht si në klientin e hollë ashtu edhe në atë të internetit.

Detyra të tjera përfshijnë zhvillimin e arkitekturës, rifaktorimin, përmirësimin e performancës dhe besueshmërisë. Për shembull, një nga drejtimet është lëvizja e mëtejshme drejt një modeli pune asinkron. Disa nga funksionalitetet e klientit të internetit janë ndërtuar aktualisht në një model sinkron të ndërveprimit me serverin. Modeli asinkron tani po bëhet më i rëndësishëm në shfletues (dhe jo vetëm në shfletues), dhe kjo na detyron të modifikojmë klientin e uebit duke zëvendësuar thirrjet sinkrone me ato asinkrone (dhe duke rifaktoruar kodin në përputhje me rrethanat). Kalimi gradual në një model asinkron shpjegohet me nevojën për të mbështetur zgjidhjet e lëshuara dhe përshtatjen e tyre graduale.

Burimi: www.habr.com

Shto një koment