Circa u cliente web 1C

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:

Circa u cliente web 1C

A stessa finestra in u cliente web (in u navigatore Chrome):

Circa u cliente web 1C

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.

Circa u cliente web 1C

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ì:

  1. Mostra l'interfaccia d'utilizatore
  2. 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:

  1. WebTools - biblioteche spartute usate da altri prughjetti (includemu ancu Google Closure Library).
  2. Elementu di cuntrollu Documentu furmatu (implementatu in JavaScript sia in u cliente sottile sia in u cliente web)
  3. Elementu di cuntrollu Scheduler (implementatu in JavaScript sia in u cliente sottile sia in u cliente web)
  4. 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.

Circa u cliente web 1C

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:

/**
 * @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;
}

È 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.

Circa u cliente web 1C

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.

Circa u cliente web 1C
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:

  • per travaglià cù i schedari
  • per travaglià cù a criptografia
  • travaglià cun cumpunenti esterni

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.

Source: www.habr.com

Add a comment