NjĂ« nga karakteristikat e kĂ«ndshme tĂ« teknologjisĂ« 1C:NdĂ«rmarrje Ă«shtĂ« se zgjidhja aplikative e zhvilluar me teknologjinĂ« e formave tĂ« menaxhuara mund tĂ« ekzekutohet si nĂ« klientin e hollĂ« (tĂ« ekzekutueshĂ«m) nĂ«n Windows, Linux, MacOS X, ashtu si dhe si klient web nĂ«n 5 shfletues â Chrome, Internet Explorer, Firefox, Safari, Edge, dhe gjithçka â pa ndryshuar kodin burimor tĂ« aplikacionit. PĂ«r mĂ« tepĂ«r â aplikacioni nĂ« klientin e hollĂ« dhe nĂ« shfletues funksionon dhe duket praktikisht identik.
Gjeni 10 dallime (në fund 2 imazhe):
Dritarja e klientit të hollë në Linux:

Po e njëjta dritare në klientin web (në shfletuesin Chrome):

Pse e bëmë klientin web? Të themi disi me stil, një detyrë e tillë na e dha koha. Që prej kohësh puna përmes Internetit është bërë një kusht i nevojshëm për aplikacionet e biznesit. Në fillim shtuam mundësinë e punës përmes Internetit për klientin tonë të hollë (disa nga konkurrentët tanë, për t'iu përmendur, e ndalën aty; të tjerë, përkundrazi, e braktisën klientin e hollë dhe u kufizuan në realizimin e klientit web). Ne vendosëm t'u ofrojmë përdoruesve tanë mundësinë të zgjedhin atë variant klienti që u përshtatet më mirë.

Shtimi i mundësisë për të punuar përmes Internetit për klientin e hollë ishte një projekt i madh me një ndryshim të plotë të arkitekturës së ndërveprimit klient-server. Krijimi i klientit web ishte një projekt krejtësisht i ri, që filloi nga zero.
Formulimi i detyrës
Pra, kërkesat për projektin: klienti web duhet të bëjë të njëjtën gjë si klienti i hollë, pra:
- Të shfaqë ndërfaqen e përdoruesit
- Të ekzekutojë kodin e klientit, i shkruar në gjuhën 1C
NjĂ« ndĂ«rfaqe pĂ«rdoruesi nĂ« 1C pĂ«rshkruhet nĂ« redaktorin vizual, por nĂ« mĂ«nyrĂ« deklarative, pa vendosjen pikĂ«-pikĂ« tĂ« elementeve; pĂ«rdoren rreth tridhjetĂ« lloje elementesh tĂ« ndĂ«rfaqes â butona, fushat e hyrjes (tekstuale, numerike, datĂ« / kohĂ«), lista, tabela, grafikĂ« etj.
Kodi i klientit në gjuhën 1C mund të përmbajë thirrje nga serveri, punë me burime lokale (skedarë etj.), printim dhe shumë të tjera.
Si klienti i hollĂ« (nĂ« punĂ«n pĂ«rmes webit), ashtu edhe klienti web pĂ«rdorin tĂ« njĂ«jtin grup shĂ«rbimesh web pĂ«r komunikim me serverin e aplikacioneve 1C. Implementimi te klientĂ«t natyrisht Ă«shtĂ« i ndryshĂ«m â klienti i hollĂ« Ă«shtĂ« shkruar nĂ« C++, klienti web â nĂ« JavaScript.
Pak histori
Projektin e krijimit të klientit web filloi në vitin 2006, me një ekip të përbërë mesatarisht nga 5 persona. Në faza të veçanta të projektit u angazhuan zhvillues për të realizuar funksionalitete specifike (dokumente tabelarë, diagramë, etj.); zakonisht, këta ishin ata të njëjtët zhvillues që kishin krijuar këto funksionalitete në klientin e hollë. Pra, zhvilluesit shkruanin nga e para në JavaScript komponentët, që më parë i kishin krijuar në C++.
Që në fillim ne hodhëm poshtë idenë e ndonjë konverzimi automatik (edhe nëse pjesor) të kodit të C++ të klientit të hollë në klientin web JavaScript për shkak të ndryshimeve të forta konceptuale midis këtyre dy gjuhëve; klienti web u shkrua në JavaScript nga një faqe e bardhë.
NĂ« iteracionet e para tĂ« projektit, klienti web konvertonte kodin e klientit nĂ« gjuhĂ«n e integruar 1C direkt nĂ« JavaScript. Klienti i hollĂ« funksionon ndryshe â kodi nĂ« gjuhĂ«n e integruar 1C kompilohen nĂ« kod bajt, dhe pastaj ky kod bajt interpretohet nĂ« klient. MĂ« vonĂ«, klienti web filloi tĂ« bĂ«nte tĂ« njĂ«jtĂ«n â sĂ« pari, kjo ofroi njĂ« fitim nĂ« performancĂ«, sĂ« dyti, lejoj qĂ« tĂ« unifikohej arkitektura e klientĂ«ve tĂ« hollĂ« dhe web.
Versioni i parĂ« i platformĂ«s 1C:NdĂ«rmarrje me mbĂ«shtetje pĂ«r klientin web doli nĂ« vitin 2009. Klienti web atĂ«herĂ« mbĂ«shteste 2 shfletues â Internet Explorer dhe Firefox. NĂ« planet fillestare ishte mbĂ«shtetje pĂ«r Opera, por pĂ«r shkak tĂ« problemeve tĂ« pandreqshme nĂ« atĂ« kohĂ« me trajtuesit e mbylljes sĂ« aplikacionit nĂ« Opera (nuk arrihej me 100% siguri tĂ« gjurmohej se kur aplikacioni mbyllej, dhe nĂ« atĂ« moment tĂ« kryhej procedura e shkĂ«putjes nga serveri i aplikacioneve 1C) nga kĂ«to plane duhej tĂ« tĂ«rhiqeshim.
Struktura e projektit
Në tërësi, platforma 1C:Ndërmarrje ka 4 projekte, të shkruara në JavaScript:
- WebTools â biblioteka tĂ« zakonshme, tĂ« pĂ«rdorura nga projektet e tjera (kĂ«tĂ« pĂ«rfshijmĂ« gjithashtu ).
- Element i menaxhimit (implementuar në JavaScript si në klientin e hollë ashtu dhe në klientin web)
- Element i menaxhimit (implementuar në JavaScript si në klientin e hollë ashtu dhe në klientin web)
- Klienti web
Struktura e çdo projekti i ngjan strukturĂ«s sĂ« projekteve Java (ose projekteve .NET â siç ju pĂ«rgjigjet); ne kemi hapĂ«sira emĂ«rtimi, dhe secila hapĂ«sirĂ« emĂ«rtimi ndodhet nĂ« njĂ« dosje tĂ« veçantĂ«. Brenda dosjes ndodhen skedarĂ« dhe klasa tĂ« hapĂ«sirĂ«s emĂ«rtimi. NĂ« projektin e klientit web ka rreth 1000 skedarĂ«.
Strukturalisht, klienti web ndahet në mënyrë të gjerë në nën-sistemat e mëposhtme:
- Ndërfaqja e menaxhuar e aplikacionit klient
- Ndërfaqja e përgjithshme e aplikacionit (menutë sistemore, panelet)
- NdĂ«rfaqja e formave tĂ« menaxhuara, duke pĂ«rfshirĂ«, mes tjerash, rreth 30 elementĂ« kontrolli (butona, lloje tĂ« ndryshme fushash hyrĂ«se â tekstuale, numerike, datĂ«/kohĂ« etj., tabela, lista, grafikĂ« etj.)
- Modeli objektor, i disponueshëm për zhvilluesit në klient (përgjithësisht mbi 400 lloje: modeli objektor i ndërfaqes së menaxhuar, konfigurimet e kompozimit të të dhënave, formatimi me kusht etj.)
- Interpreatori i gjuhës së integruar 1C
- Zgjatjet e shfletuesve (përdoren për funksionalitetet që nuk mbështeten në JavaScript)
- Puna me kriptografinë
- Punimi me skedarët
- Teknologjia e komponenteve të jashtme, që lejon përdorimin e tyre si në klientin e hollë, ashtu edhe në klientin web
Veçoritë e zhvillimit
Implementimi i të gjitha asaj që përshkruhet më sipër në JavaScript - është një detyrë e vështirë. Ndoshta, klienti web 1C është një nga aplikacionet më të mëdha client-side të shkruara në JavaScript - rreth 450.000 rreshta. Ne aktivisht përdorim në kodin e klientit web një qasje objektivisht-orientuar, që e thjeshton punën me një projekt kaq të madh.
PĂ«r tĂ« minimizuar madhĂ«sinĂ« e kodit tĂ« klientit, nĂ« fillim pĂ«rdorĂ«m obfuskatorin tonĂ« tĂ« vet, dhe duke filluar nga versioni i platformĂ«s 8.3.6 (tetor 2014) filluam tĂ« pĂ«rdorim . Efekti i pĂ«rdorimit nĂ« numra â madhĂ«sia e kuadrit tĂ« klientit web pas obfuskimit:
- Obfuskatori ynë - 1556 kB
- Google Closure Compiler - 1073 kB
Përdorimi i Google Closure Compiler na ndihmoi të rrisim performancën e klientit web me 30% krahasuar me obfuskatorin tonë të vet. Përveç kësaj, volumi i memories e përdorur nga aplikacioni është zvogëluar me 15-25% (në varësi të shfletuesit).
Google Closure Compiler punon shumë mirë me kodin objektivisht-orientuar, prandaj efikasiteti i tij pikërisht për klientin web është maksimal. Closure Compiler bën disa gjëra të mira për ne:
- Kontrolli statik i tipeve në fazën e ndërtimit të projektit (sigurohet nga mbulimi i kodit me annotacione JSDoc). Rezultati është një tipizim statik, shumë të afërt me nivelin e tipizimit në C++. Kjo ndihmon të kapim një përqindje të madhe të gabimeve në fazën e kompilimit të projektit.
- Reduktimi i madhësisë së kodit përmes obfuskimit
- Një sërë optimizimesh të kodit të ekzekutueshëm, për shembull, si:
- zëvendësimet në linjë të funksioneve. Thirrja e një funksioni në JavaScript është një operacion relativisht i shtrenjtë, dhe zëvendësimet në linjë të metodave të vogla që përdoren shpesh rrisin ndjeshëm performancën e kodit.
- Numërimi i konstantave në fazën e kompilimit. Nëse shprehja varet nga një konstantë, vlerya reale e konstantës do të vendoset atje.
Si mjedis zhvillimi për klientin në ueb ne përdorim WebStorm.
Për analizën e kodit ne përdorim , ku integrojmë analizatorët statikë të kodit. Me ndihmën e analizatorëve ne monitorojmë degradimin e cilësisë së kodit burimor në JavaScript dhe përpiqemi ta parandalojmë atë.

Cilat detyra kemi zgjidhur/zgjidhim
Gjatë zbatimit të projektit ne u përballëm me një sërë detyrash interesante që duhej të zgjidhnim.
Shkëmbimi i të dhënave me serverin dhe ndërmjet dritareve
Ekzistojnë situata kur obfusikimi i kodit burimor mund të pengojë funksionimin e sistemit. Kodi, i jashtëm ndaj kodit ekzekutiv të klientit në ueb, për shkak të obfusikimit, mund të ketë emra funksionesh dhe parametrash që dallojnë nga ato që kodi ynë ekzekutiv pret. Kod i jashtëm për ne është:
- Kodi që vjen nga serveri në formën e strukturave të dhënash
- Kodi i një dritareje tjetër të aplikacionit
Për të shmangur obfusikimin gjatë ndërveprimit 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 obfusikimin gjatë ndërveprimit me dritare të tjera ne përdorim ashtuquajturat interface të eksportuara (interface ku të gjitha metodat janë të eksportuara).
/**
* ĐĐșŃĐżĐŸŃŃĐžŃŃĐ”ĐŒŃĐč ĐžĐœŃĐ”ŃŃĐ”ĐčŃ ĐșĐŸĐœŃŃĐŸĐ»Đ° 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 para se të bëhej e zakonshme)
Ashtu si të gjithë zhvilluesit që merren me UI-në e komplikuar në web, ne u kuptuam shpejt se DOM-i nuk është përshtatshëm për të punuar me një ndërfaqe dinamike përdoruesi. Praktikisht menjëherë u implementua një analog i Virtual DOM për të optimizuar punën me UI-në. Gjatë trajtimit të ngjarjeve, të gjitha ndryshimet në DOM ruhen në memorje dhe, vetëm pas përfundimit të të gjitha operacioneve, ndryshimet e grumbulluara aplikohen në pemën DOM.
Optimizimi i punës së klientit në web
Për të bërë që klienti ynë në web të funksionojë më shpejt, ne përpiqemi në maksimum të shfrytëzojmë mundësitë standarde të shfletuesit (CSS etj.). Kështu, paneli i komandës së formës (i vendosur pothuajse në çdo formë të aplikacionit) vizatohet ekskluzivisht me mjete të shfletuesit, duke përdorur dizajn dinamik të bazuar në CSS.

Testimi
Për testimin funksional dhe testimin e performancës përdorim një mjet të prodhuar vetë (shkruar në Java dhe C++), si dhe një grup testesh të ndërtuara mbi bazën e .
Mjeti ynĂ« Ă«shtĂ« universal â ai lejon tĂ« testoheshin pothuajse çdo program dritare, prandaj Ă«shtĂ« i pĂ«rshtatshĂ«m pĂ«r testimin e klientĂ«ve tĂ« hollĂ«, si dhe pĂ«r klientĂ«t nĂ« internet. Mjeti regjistron veprimet e pĂ«rdoruesit qĂ« ka nisur zgjidhjen aplikative "1C", nĂ« njĂ« skenar skenari. NĂ« tĂ« njĂ«jtĂ«n kohĂ«, bĂ«het regjistrimi i imazheve tĂ« zonĂ«s sĂ« punĂ«s sĂ« ekranit â referencat. NĂ« kontrollin e versioneve tĂ« reja tĂ« klientit nĂ« internet, skenarĂ«t ekzekutohen pa pjesĂ«marrjen e pĂ«rdoruesit. NĂ« rast se ekrani i shkrepjes nuk pĂ«rputhet me referencĂ«n nĂ« ndonjĂ« hap, testi konsiderohet i dĂ«shtuar, pas sĂ« cilĂ«s specialisti i cilĂ«sisĂ« kryen hetimin â nĂ«se Ă«shtĂ« njĂ« gabim apo njĂ« ndryshim i planifikuar nĂ« sjelljen e sistemit. NĂ« rastin e sjelljes sĂ« planifikuar, referencat automatikisht zĂ«vendĂ«sohen me tĂ« reja.
Mjeti gjithashtu kryen matje të performancës së aplikacioneve me saktësi deri në 25 milisekonda. Në disa raste ne e këto pjesë të skenarit (p.sh., disa herë përsëritim hyrjen e porosisë) për të analizuar degradimin e kohës së ekzekutimit me kalimin e kohës. Të gjitha rezultatet e matjeve regjistrohen në log për analiza.

Mjeti ynë i testimit dhe aplikacioni i testuar
Mjeti ynĂ« dhe Selenium plotĂ«sojnĂ« njĂ«ri-tjetrin; pĂ«r shembull, nĂ«se ndonjĂ« buton nĂ« njĂ« nga ekranet ka ndryshuar vendndodhjen e tij â Selenium nuk mund ta ndjekĂ« kĂ«tĂ«, por mjeti ynĂ« do ta vĂ«rejĂ«, sepse bĂ«n njĂ« krahasim pixel pĂ«r pixel tĂ« shkrepjes me referencĂ«n. Gjithashtu, mjeti Ă«shtĂ« nĂ« gjendje tĂ« ndjekĂ« problemet me trajtimin e hyrjeve nga tastiera ose mouse-i, pasi ato janĂ« pikĂ«risht ato qĂ« ai pĂ«rsĂ«rit.
Testet nĂ« tĂ« dy mjetet (tonin dhe Selenium) ekzekutojnĂ« skenarĂ« standard tĂ« funksionimit nga zgjidhjet tona aplikative. Testet ekzekutohen automatikisht pas ndĂ«rtimit tĂ« pĂ«rditshĂ«m tĂ« platformĂ«s "1C:Enterprise". NĂ« rast tĂ« ngadalĂ«simit tĂ« punĂ«s sĂ« skenarĂ«ve (krahasuar me ndĂ«rtimin e mĂ«parshĂ«m), ne kryejmĂ« njĂ« hetim dhe eliminojmĂ« shkakun e ngadalĂ«simit. KritĂ«ri ynĂ« Ă«shtĂ« i thjeshtĂ« â ndĂ«rtimi i ri duhet tĂ« funksionojĂ« jo mĂ« ngadalĂ« se ndĂ«rtimi i mĂ«parshĂ«m.
PĂ«r hetimin e incidenteve tĂ« ngadalĂ«simit tĂ« punĂ«s, zhvilluesit pĂ«rdorin mjete tĂ« ndryshme; zakonisht pĂ«rdoret e kompanisĂ« . Regjistrohen loget e ekzekutimit tĂ« operacioneve me probleme nĂ« versionin e mĂ«parshĂ«m dhe atĂ« tĂ« ri, pastaj loget analizohen. NĂ« kĂ«tĂ« rast, koha e ekzekutimit tĂ« operacioneve individuale (nĂ« milisekonda) mund tĂ« mos jetĂ« faktori vendimtar â nĂ« shfletues herĂ« pas here nisin procese shĂ«rbimi, si pastrimi i mbetjeve, qĂ« mund tĂ« ndikojnĂ« nĂ« kohĂ«n e funksioneve dhe tĂ« deformojnĂ« imazhin. Parametra mĂ« pĂ«rkatĂ«s kĂ«tu do tĂ« jenĂ« numri i instrukcioneve JavaScript tĂ« kryera, numri i operacioneve atomike mbi DOM etj. NĂ«se numri i instrukcioneve/operacioneve nĂ« tĂ« njĂ«jtin skenar nĂ« versionin e ri Ă«shtĂ« rritur â kjo zakonisht do tĂ« thotĂ« njĂ« rĂ«nie tĂ« performancĂ«s qĂ« duhet tĂ« rregullohet.
Gjithashtu, njëra nga arsyet për rënien e performancës mund të jetë se Google Closure Compiler për ndonjë arsye nuk arriti të bëjë zëvendësimin inline të funkcioneve (për shembull, sepse funksioni është rekursiv ose virtual). Në këtë rast, ne përpiqemi të rregullojmë situatën duke riparë kodin burimor.
Zgjatjet e shfletuesit
Në raste kur zgjidhja aplikative ka nevojë për funksionalitete që nuk janë në JavaScript, ne përdorim zgjatjet e shfletuesit:
- për punë me skedarët
- për punë me kriptografinë
- punë me
Zgjatjet tona pĂ«rbĂ«hen nga dy pjesĂ«. Pjesa e parĂ« Ă«shtĂ« ajo qĂ« quhet zgjatje e shfletuesit (zakonisht, zgjatje tĂ« shkruara nĂ« JavaScript pĂ«r Chrome dhe Firefox), tĂ« cilat ndĂ«rveprojnĂ« me pjesĂ«n e dytĂ« â njĂ« zgjatje binare qĂ« realizon funksionalitetin qĂ« na nevojitet. Duhet tĂ« pĂ«rmendet se ne shkruajmĂ« 3 versione tĂ« zgjatjeve binare â pĂ«r Windows, Linux dhe MacOS. Zgjatja binare jepet si pjesĂ« e platformĂ«s 1C:Enterprise dhe ndodhet nĂ« serverin e aplikacioneve 1C. NĂ« thirrjen e parĂ« nga klienti ueb, ajo ngarkohet nĂ« kompjuterin e klientit dhe instalohet nĂ« shfletues.
Kur punojmĂ« nĂ« Safari, zgjatjet tona pĂ«rdorin NPAPI, ndĂ«rsa nĂ« Internet Explorer â teknologjinĂ« ActiveX. nuk mbĂ«shtet zgjatje, prandaj klienti ueb kĂ«tu punon me kufizime.
Zhvillimi në vazhdim
Një nga grupet e detyrave për ekipin e zhvillimit të klientit web është avancimi i funksionaliteteve. Funksionaliteti i klientit web duhet të jetë identik me atë të klientit të hollë, të gjitha funksionalitetet e reja implementohen njëkohësisht në të dyja, në klientin e hollë dhe atë web.
Detyra të tjera përfshijnë zhvillimin e arkitekturës, ristrukturimin, përmirësimin e performancës dhe besueshmërisë. Për shembull, një nga drejtimet është lëvizja përpara në modelin e punës asinkron. Një pjesë e funksionalitetit të klientit web aktualisht është ndërtuar mbi modelin e ndërveprimit sinkron 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 web duke zëvendësuar thirrjet sinkrone me ato asinkrone (dhe duke realizuar përkatësisht ristrukturimin e kodit). Kalimi gradual në modelin asinkron shpjegohet nga nevoja për të mb supportuar zgjidhjet e publikuara dhe përshtatjen e tyre afatshkurtër.
Burimi: habr.com
