Una di e belle caratteristiche di a tecnulugia 1C:Enterprise hè chì a soluzione di l'applicazione, sviluppata cù a tecnulugia di forme gestite, pò esse lanciata sia in un cliente sottile (eseguibile) per Windows, Linux, MacOS X, sia cum'è cliente web per 5 navigatori - Chrome, Internet Explorer, Firefox, Safari, Edge, è tuttu questu senza cambià u codice fonte di l'applicazione. Inoltre, esternamente l'applicazione in u cliente thin è in u navigatore funziona è pare quasi identica.
Truvate 10 differenze (2 ritratti sottu u cut):
Finestra Thin Client in Linux:
A stessa finestra in u cliente web (in u navigatore Chrome):
Perchè avemu fattu un cliente web? Per dì un pocu pateticu, u tempu hà stabilitu un tali compitu per noi. U travagliu nantu à Internet hè statu longu un prerequisite per l'applicazioni cummerciale. Prima, avemu aghjustatu a capacità di travaglià via Internet per u nostru cliente thin (alcuni di i nostri cuncurrenti, per via, si fermanu quì; altri, à u cuntrariu, abbandunonu u cliente thin è si limitanu à implementà un cliente web). Avemu decisu di dà à i nostri utilizatori l'uppurtunità di sceglie l'opzione di u cliente chì li cunvene megliu.
L'aghjunzione di capacità basate in u web à u cliente thin era un grande prughjettu cù un cambiamentu cumpletu in l'architettura client-server. Crià un cliente web hè un prughjettu completamente novu, partendu da zero.
Formulazione di u prublema
Dunque, i bisogni di u prugettu: u cliente web deve fà u listessu cum'è u cliente sottile, vale à dì:
Mostra l'interfaccia d'utilizatore
Eseguite u codice cliente scrittu in lingua 1C
L'interfaccia d'utilizatore in 1C hè descritta in un editore visuale, ma dichjarazione, senza arrangiamentu pixel per pixel di elementi; Circa trè decine di tipi di elementi di l'interfaccia sò usati - buttoni, campi di input (testu, numericu, data / ora), listi, tavule, grafici, etc.
U codice di u cliente in a lingua 1C pò cuntene chjamati di u servitore, travagliendu cù risorse lucali (fichi, etc.), stampa, è assai più.
Sia u cliente thin (quandu travaglia via u web) è u cliente web utilizanu u listessu settore di servizii web per cumunicà cù u servitore di l'applicazione 1C. L'implementazioni di u cliente, di sicuru, sò diffirenti - u cliente thin hè scrittu in C ++, u cliente web hè scrittu in JavaScript.
Un pocu di storia
U prughjettu di u cliente web hà iniziatu in 2006, cù una squadra di (in media) 5 persone. In certi fasi di u prugettu, i sviluppatori sò stati implicati per implementà funziunalità specifichi (documentu di spreadsheet, diagrammi, etc.); in regula, questi eranu i stessi sviluppatori chì anu fattu sta funziunalità in u cliente thin. Quelli. i sviluppatori anu riscritto cumpunenti in JavaScript chì avianu creatu prima in C ++.
Dapoi u principiu, avemu rifiutatu l'idea di qualsiasi cunversione automatica (ancu parziale) di u còdice di cliente sottile C++ in u cliente web JavaScript per via di e forti differenze cuncettuali trà e duie lingue; u cliente web hè statu scrittu in JavaScript da zero.
In i primi iterazioni di u prugettu, u cliente web cunvertisce u codice di u cliente in a lingua 1C integrata direttamente in JavaScript. U thin client agisce in modu diversu - u codice in a lingua 1C integrata hè compilatu in bytecode, è dopu stu bytecode hè interpretatu nantu à u cliente. In seguitu, u cliente web cuminciò à fà u listessu - prima, hà datu un guadagnu di rendiment, è in segundu, hà permessu di unificà l'architettura di i clienti sottili è web.
A prima versione di a piattaforma 1C: Enterprise cù supportu di u cliente web hè stata liberata in 2009. U cliente web à quellu tempu supportava 2 navigatori - Internet Explorer è Firefox. I piani originali includenu supportu per Opera, ma per via di prublemi insurmontable in quellu tempu cù i gestori di chjusi di l'applicazioni in Opera (ùn era micca pussibule di seguità cù a certezza di 100% chì l'applicazione si chjude, è in quellu mumentu eseguisce a prucedura di scollegamentu da u 1C server application) da questi piani anu da esse abbandunatu.
Struttura di u prugettu
In totale, a piattaforma 1C: Enterprise hà 4 prughjetti scritti in JavaScript:
WebTools - biblioteche spartute usate da altri prughjetti (includemu ancu Google Closure Library).
Elementu di cuntrollu Documentu furmatu (implementatu in JavaScript sia in u cliente sottile sia in u cliente web)
Elementu di cuntrollu Scheduler (implementatu in JavaScript sia in u cliente sottile sia in u cliente web)
Client web
A struttura di ogni prughjettu s'assumiglia à a struttura di prughjetti Java (o prughjetti .NET - quale hè più vicinu); Avemu namespaces, è ogni namespace hè in un cartulare separatu. Dentru u cartulare ci sò schedarii è classi di namespace. Ci sò circa 1000 schedari in u prughjettu di u cliente web.
Strutturalmente, u cliente web hè largamente divisu in i seguenti sottosistemi:
Interfaccia di l'applicazione cliente gestita
Interfaccia generale di l'applicazione (menu di sistema, pannelli)
Interfaccia di forme gestite, cumprese, frà altre cose, circa 30 cuntrolli (buttoni, vari tipi di campi di input - testu, numericu, data / ora, etc., tavule, listi, grafici, etc.)
U mudellu di l'ughjettu dispunibule per i sviluppatori nantu à u cliente (più di 400 tippi in totale: mudellu d'ughjettu di l'interfaccia gestita, paràmetri di layout di dati, stile cundizionale, etc.)
Interprete di a lingua integrata 1C
Estensioni di u navigatore (aduprate per a funziunalità micca supportata in JavaScript)
U travagliu cù a criptografia
U travagliu cù i schedari
Tecnulugia di cumpunenti esterni, chì li permettenu di esse usatu in i clienti sottili è web
Funzioni di sviluppu
Implementà tuttu ciò chì sopra in JavaScript ùn hè micca faciule. Forse u cliente web 1C hè una di e più grandi applicazioni di u cliente scritte in JavaScript - circa 450.000 XNUMX linee. Utilizemu attivamente un approcciu orientatu à l'ughjettu in u codice di u cliente web, chì simplificà u travagliu cù un prughjettu cusì grande.
Per minimizzà a dimensione di u codice di u cliente, avemu prima utilizatu u nostru propiu obfuscator, è cuminciendu cù a versione di piattaforma 8.3.6 (ottobre 2014) avemu cuminciatu à aduprà Google Closure Compiler. L'effettu di l'usu in numeri - a dimensione di u quadru di u cliente web dopu l'obfuscazione:
Propiu obfuscator - 1556 kb
Google Closure Compiler - 1073 kb
Utilizà Google Closure Compiler ci hà aiutatu à migliurà a prestazione di u cliente web da 30% paragunatu à u nostru propiu obfuscator. Inoltre, a quantità di memoria cunsumata da l'applicazione hè diminuita da 15-25% (secondu u navigatore).
Google Closure Compiler funziona assai bè cù u codice orientatu à l'ughjettu, cusì a so efficienza per u cliente web hè u più altu pussibule. Closure Compiler fa un pocu di cose boni per noi:
Verificazione di u tipu staticu in a fase di creazione di u prughjettu (assicurà chì copre u codice cù annotazioni JSDoc). U risultatu hè una scrittura statica, assai vicinu à u nivellu di scrive in C++. Questu aiuta à catturà un percentinu abbastanza grande di errori in a fase di compilazione di u prugettu.
Riduce a dimensione di u codice per l'obfuscazione
Una quantità di ottimisazioni di u codice eseguitu, per esempiu, cum'è:
sostituzione di funzioni in linea. Chjamà una funzione in JavaScript hè una operazione abbastanza caru, è e sustituzzioni inline di metudi chjuchi spessu usati acceleranu significativamente u codice.
Custanti custanti in tempu di compilazione. Se una espressione dipende da una constante, u valore attuale di a constante serà sustituitu in questu
Utilizemu WebStorm cum'è u nostru ambiente di sviluppu di u cliente web.
Per l'analisi di codice avemu aduprà soundQube, induve integremu analizatori di codice staticu. Utilizendu analizatori, monitoremu a degradazione di a qualità di u codice fonte JavaScript è pruvate à prevene.
Chì prublemi avemu risoltu?
Durante l'implementazione di u prugettu, avemu scontru una quantità di prublemi interessanti chì avemu avutu da risolve.
Scambià dati cù u servitore è trà Windows
Ci sò situazioni induve l'obfuscazione di u codice fonte pò interferiscenu cù u funziunamentu di u sistema. U codice esterno à u codice eseguibile di u cliente web, per via di l'obfuscazione, pò avè nomi di funzioni è paràmetri chì sò diffirenti di quelli chì u nostru codice eseguibile aspetta. U codice esternu per noi hè:
Codice chì vene da u servitore in forma di strutture di dati
Codice per una altra finestra di l'applicazione
Per evità l'obfuscazione quandu interagisce cù u servitore, usemu a tag @expose:
È per evità l'obfuscazione quandu interagisce cù l'altri finestri, usemu l'interfacce esportati chjamati (interfaces in quale tutti i metudi sò esportati).
/**
* Экспортируемый интерфейс контрола 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 (){}
Avemu usatu Virtual DOM prima di diventà mainstream)
Cum'è tutti i sviluppatori chì trattanu di UI Web cumplessi, avemu capitu rapidamente chì u DOM hè pocu adattatu per travaglià cù interfacce d'utilizatori dinamichi. Quasi subitu, un analogu di Virtual DOM hè statu implementatu per ottimisà u travagliu cù l'UI. Duranti l'elaborazione di l'avvenimenti, tutti i cambiamenti DOM sò guardati in memoria è, solu quandu tutte l'operazioni sò finite, i cambiamenti accumulati sò appiicati à l'arburu DOM.
Ottimisazione di u cliente web
Per fà u nostru cliente web travaglià più veloce, pruvate d'utilizà e capacità standard di u navigatore (CSS, etc.) à u massimu. Cusì, u pannellu di cumandamentu di forma (situatu nantu à quasi ogni forma di l'applicazione) hè resu solu utilizendu strumenti di navigatore, utilizendu un layout dinamicu basatu in CSS.
Prucessioni
Per i testi funziunali è di prestazione, usemu un strumentu propiu (scritto in Java è C++), è ancu una suite di teste custruita nantu à sélénium.
U nostru strumentu hè universale - vi permette di pruvà quasi ogni prugramma di finestra, è dunque hè adattatu per pruvà un cliente sottile è un cliente web. L'uttellu registra l'azzioni di l'utilizatore chì hà lanciatu a suluzione di l'applicazione 1C in un schedariu di script. À u listessu tempu, l'imaghjini di l'area di travagliu di u screnu - standard - sò arregistrati. Quandu u monitoraghju di e novi versioni di u cliente web, i scripts sò ghjucati senza participazione di l'utilizatori. In i casi induve a screenshot ùn currisponde à u riferimentu in ogni passu, a prova hè cunsiderata falluta, dopu chì un specialista di qualità face una investigazione per stabilisce s'ellu hè un errore o un cambiamentu pianificatu in u cumpurtamentu di u sistema. In casu di cumpurtamentu pianificatu, i normi sò automaticamente rimpiazzati cù novi.
L'uttellu misura ancu u rendiment di l'applicazione cù una precisione di finu à 25 millisecondi. In certi casi, avemu loop parti di u script (per esempiu, ripetendu l'entrata di l'ordine parechje volte) per analizà a degradazione di u tempu d'esekzione cù u tempu. I risultati di tutte e misurazioni sò registrati in un logu per l'analisi.
U nostru strumentu di prova è applicazione in prova
U nostru strumentu è Selenium cumplementarii; per esempiu, se qualchì buttone nantu à una di e schermi hà cambiatu u so locu, Selenium ùn pò micca seguità questu, ma u nostru strumentu hà da nutà, perchè face un paragone pixel per pixel di a screenshot cù u standard. L'uttellu hè ancu capaci di seguità i prublemi cù u processu di input da u teclatu o u mouse, postu chì questu hè esattamente ciò chì riproduce.
I testi nantu à i dui arnesi (a nostra è Selenium) eseguite scenarii di travagliu tipici da e nostre soluzioni d'applicazione. I testi sò lanciati automaticamente dopu a custruzione di ogni ghjornu di a piattaforma 1C: Enterprise. Se i scripts sò più lenti (paragunatu à a custruzione precedente), investighemu è risolvemu a causa di a rallentazione. U nostru criteriu hè simplice - a nova custruzzione ùn deve micca travaglià più lenta chè a precedente.
I sviluppatori utilizanu diverse arnesi per investigà incidenti di rallentamentu; principarmenti usatu Edizione Dynatrace AJAX cumpagnia di pruduzzione DynaTrace. I logs di l'esekzione di l'operazione problematica nantu à e custruzzioni previ è novi sò registrati, dopu i logs sò analizati. À u listessu tempu, u tempu d'esekzione di l'operazioni singuli (in millisecondi) ùn pò micca esse un fattore decisivu - i prucessi di serviziu, cum'è a cullizzioni di basura, sò lanciati periodicamente in u navigatore, ponu sovrappone cù u tempu d'esekzione di e funzioni è distorte a stampa. I paràmetri più pertinenti in questu casu seranu u numeru di struzzioni JavaScript eseguite, u numeru di operazioni atomiche nantu à u DOM, etc. Se u nùmeru d'istruzzioni / operazioni in u stessu script hè aumentatu in una nova versione, questu quasi sempre significa una calata di rendiment chì deve esse curretta.
Inoltre, unu di i motivi per a calata di u rendimentu pò esse chì Google Closure Compiler per una certa ragione ùn era micca capaci di realizà a sostituzione in linea di a funzione (per esempiu, perchè a funzione hè recursiva o virtuale). In questu casu, pruvemu à curregge a situazione da riscrive u codice fonte.
Estensioni di u navigatore
Quandu una suluzione di l'applicazione necessita di funziunalità chì ùn hè micca dispunibule in JavaScript, usemu estensioni di navigatore:
I nostri estensioni sò custituiti da dui parti. A prima parte hè ciò chì si chjama una estensione di navigatore (di solitu estensioni per Chrome è Firefox scritte in JavaScript), chì interagiscenu cù a seconda parte - una estensione binaria chì implementa a funziunalità chì avemu bisognu. Hè da esse citatu chì avemu scrittu 3 versioni di estensioni binari - per Windows, Linux è MacOS. L'estensione binaria hè furnita cum'è parte di a piattaforma 1C: Enterprise è si trova nantu à u servitore di l'applicazioni 1C. Quandu hè chjamatu per a prima volta da un cliente web, hè telecaricatu à l'urdinatore di u cliente è installatu in u navigatore.
Quandu eseguite in Safari, e nostre estensioni utilizanu NPAPI; quandu eseguite in Internet Explorer, usanu tecnulugia ActiveX. Microsoft Edge ùn sustene micca ancu l'estensioni, cusì u cliente web in questu travaglia cù restrizioni.
Ulteriore sviluppu
Unu di i travaglii per a squadra di sviluppu di u cliente web hè u sviluppu ulteriore di e funziunalità. A funziunalità di u cliente web deve esse identica à a funziunalità di u cliente sottile; tutte e novi funziunalità sò implementate simultaneamente in i clienti sottili è web.
Altri compiti includenu u sviluppu di l'architettura, refactoring, migliurà u rendiment è l'affidabilità. Per esempiu, una di e direzzione hè più muvimentu versu un mudellu di travagliu asincronu. Alcune di e funziunalità di u cliente web hè attualmente custruitu nantu à un mudellu sincronu di interazzione cù u servitore. U mudellu asincronu hè avà diventatu più pertinenti in i navigatori (è micca solu in i navigatori), è questu ci forza à mudificà u cliente web rimpiazzendu e chjama sincrone cù l'asynchronous (è refactoring u codice per quessa). A transizione graduale à un mudellu asincronu hè spiegatu da a necessità di sustene e soluzioni liberate è a so adattazione graduali.