Om 1C-webklienten

En av de fine egenskapene til 1C:Enterprise-teknologi er at applikasjonsløsningen, utviklet ved bruk av administrerte skjemateknologi, kan lanseres både i en tynn (kjørbar) klient for Windows, Linux, MacOS X, og som en nettklient for 5 nettlesere - Chrome, Internet Explorer, Firefox, Safari, Edge og alt dette uten å endre applikasjonens kildekode. Dessuten fungerer applikasjonen eksternt i tynnklienten og i nettleseren og ser nesten identisk ut.
Finn 10 forskjeller (2 bilder under snittet):

Tynnklientvindu på Linux:

Om 1C-webklienten

Det samme vinduet i nettklienten (i Chrome-nettleseren):

Om 1C-webklienten

Hvorfor laget vi en nettklient? For å si det litt patetisk, har tiden satt en slik oppgave for oss. Arbeid over Internett har lenge vært en forutsetning for forretningsapplikasjoner. Først la vi til muligheten til å jobbe via Internett for vår tynnklient (noen av våre konkurrenter stoppet forresten ved dette; andre tvert imot forlot den tynne klienten og begrenset seg til å implementere en nettklient). Vi bestemte oss for å gi våre brukere muligheten til å velge det klientalternativet som passer dem best.

Om 1C-webklienten

Å legge til nettbaserte funksjoner til den tynne klienten var et stort prosjekt med en fullstendig endring i klient-server-arkitekturen. Å lage en nettklient er et helt nytt prosjekt, som starter fra bunnen av.

Formulering av problemet

Så, prosjektkravene: webklienten må gjøre det samme som tynnklienten, nemlig:

  1. Vis brukergrensesnitt
  2. Utfør klientkode skrevet på 1C-språk

Brukergrensesnittet i 1C er beskrevet i en visuell editor, men deklarativt, uten piksel-for-piksel arrangement av elementer; Omtrent tre dusin typer grensesnittelementer brukes - knapper, inndatafelt (tekst, numerisk, dato/klokkeslett), lister, tabeller, grafer, etc.

Klientkode på 1C-språket kan inneholde serveranrop, arbeid med lokale ressurser (filer osv.), utskrift og mye mer.

Både den tynne klienten (når du arbeider via nettet) og nettklienten bruker samme sett med webtjenester for å kommunisere med 1C-applikasjonsserveren. Klientimplementeringer er selvfølgelig forskjellige - den tynne klienten er skrevet i C++, nettklienten er skrevet i JavaScript.

En bit av historien

Nettklientprosjektet startet i 2006, med et team på (i gjennomsnitt) 5 personer. På visse stadier av prosjektet ble utviklere involvert for å implementere spesifikk funksjonalitet (regnearkdokument, diagrammer, etc.); som regel var dette de samme utviklerne som gjorde denne funksjonaliteten i tynnklienten. De. utviklere skrev om komponenter i JavaScript som de tidligere hadde laget i C++.

Helt fra begynnelsen avviste vi ideen om enhver automatisk (selv delvis) konvertering av C++ tynnklientkode til JavaScript-webklient på grunn av de sterke konseptuelle forskjellene mellom de to språkene; nettklienten ble skrevet i JavaScript fra bunnen av.

I de første iterasjonene av prosjektet konverterte nettklienten klientkode i det innebygde 1C-språket direkte til JavaScript. Tynnklienten opptrer annerledes - koden i det innebygde 1C-språket kompileres til bytekode, og deretter tolkes denne bytekoden på klienten. Deretter begynte webklienten å gjøre det samme - for det første ga det en ytelsesgevinst, og for det andre gjorde det mulig å forene arkitekturen til tynn- og webklientene.

Den første versjonen av 1C:Enterprise-plattformen med webklientstøtte ble utgitt i 2009. Nettklienten på den tiden støttet 2 nettlesere - Internet Explorer og Firefox. De opprinnelige planene inkluderte støtte for Opera, men på grunn av uoverstigelige problemer på det tidspunktet med applikasjonslukkingsbehandlere i Opera (det var ikke mulig å spore med 100 % sikkerhet at applikasjonen var i ferd med å stenge, og i det øyeblikket utføre frakoblingsprosedyren fra 1C-applikasjonsserveren) fra disse planene måtte forlates.

Prosjektstruktur

Totalt har 1C:Enterprise-plattformen 4 prosjekter skrevet i JavaScript:

  1. WebTools – delte biblioteker som brukes av andre prosjekter (vi inkluderer også Googles nedleggelsesbibliotek).
  2. Kontrollelement Formatert dokument (implementert i JavaScript i både tynnklienten og nettklienten)
  3. Kontrollelement Planlegger (implementert i JavaScript i både tynnklienten og nettklienten)
  4. Nettklient

Strukturen til hvert prosjekt ligner strukturen til Java-prosjekter (eller .NET-prosjekter - avhengig av hva som er nærmest); Vi har navneområder, og hvert navneområde ligger i en egen mappe. Inne i mappen er det filer og navneområdeklasser. Det er omtrent 1000 filer i webklientprosjektet.

Strukturelt er nettklienten i stor grad delt inn i følgende undersystemer:

  • Administrert klientapplikasjonsgrensesnitt
    • Generelt applikasjonsgrensesnitt (systemmenyer, paneler)
    • Grensesnitt for administrerte skjemaer, inkludert blant annet ca. 30 kontroller (knapper, ulike typer inndatafelt - tekst, numerisk, dato/klokkeslett, etc., tabeller, lister, grafer, etc.)

  • Objektmodell tilgjengelig for utviklere på klienten (over 400 typer totalt: objektmodell for administrert grensesnitt, innstillinger for datalayout, betinget styling, etc.)
  • Tolk av det innebygde 1C-språket
  • Nettleserutvidelser (brukes for funksjonalitet som ikke støttes i JavaScript)
    • Jobber med kryptografi
    • Arbeid med filer
    • Teknologi av eksterne komponenter, slik at de kan brukes i både tynne klienter og nettklienter

Utviklingsfunksjoner

Det er ikke lett å implementere alt det ovennevnte i JavaScript. Kanskje er 1C-webklienten en av de største klientsideapplikasjonene skrevet i JavaScript - omtrent 450.000 XNUMX linjer. Vi bruker aktivt en objektorientert tilnærming i nettklientkoden, noe som forenkler arbeidet med et så stort prosjekt.

For å minimere størrelsen på klientkoden brukte vi først vår egen obfuscator, og fra og med plattformversjon 8.3.6 (oktober 2014) begynte vi å bruke Google Closure Compiler. Effekten av bruk i tall – størrelsen på nettklientrammeverket etter tilsløring:

  • Egen obfuscator – 1556 kb
  • Google Closure Compiler – 1073 kb

Å bruke Google Closure Compiler hjalp oss med å forbedre ytelsen til nettklienten med 30 % sammenlignet med vår egen obfuscator. I tillegg har mengden minne som forbrukes av applikasjonen gått ned med 15-25 % (avhengig av nettleseren).

Google Closure Compiler fungerer veldig bra med objektorientert kode, så effektiviteten for nettklienten er så høy som mulig. Closure Compiler gjør noen gode ting for oss:

  • Statisk typekontroll på prosjektets byggestadium (sikker på at vi dekker koden med JSDoc-kommentarer). Resultatet er statisk skriving, veldig nært i nivå å skrive i C++. Dette bidrar til å fange opp en ganske stor prosentandel av feil på prosjektkompileringsstadiet.
  • Reduser kodestørrelsen gjennom tilsløring
  • En rekke optimaliseringer av den utførte koden, for eksempel, for eksempel:
    • inline funksjonserstatninger. Å kalle en funksjon i JavaScript er en ganske kostbar operasjon, og inline-erstatninger av ofte brukte små metoder øker koden betydelig.
    • Tellekonstanter ved kompileringstid. Hvis et uttrykk er avhengig av en konstant, vil den faktiske verdien av konstanten bli erstattet med den

Vi bruker WebStorm som vårt webklientutviklingsmiljø.

For kodeanalyse bruker vi soundQube, hvor vi integrerer statiske kodeanalysatorer. Ved å bruke analysatorer overvåker vi forringelsen av kvaliteten på JavaScript-kildekoden og prøver å forhindre det.

Om 1C-webklienten

Hvilke problemer løste/løste vi?

Under gjennomføringen av prosjektet møtte vi en rekke interessante problemer som vi måtte løse.

Utveksle data med serveren og mellom vinduer

Det er situasjoner der obfuskering av kildekoden kan forstyrre driften av systemet. Kode eksternt til nettklientens kjørbare kode, på grunn av obfuskering, kan ha funksjons- og parameternavn som avviker fra de som vår kjørbare kode forventer. Den eksterne koden for oss er:

  • Kode som kommer fra serveren i form av datastrukturer
  • Kode for et annet programvindu

For å unngå forvirring når vi samhandler med serveren, bruker vi @expose-taggen:

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

Og for å unngå tilsløring når vi samhandler med andre vinduer, bruker vi såkalte eksporterte grensesnitt (grensesnitt der alle metoder eksporteres).

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

Vi brukte Virtual DOM før det ble mainstream)

Som alle utviklere som arbeider med komplekse nettgrensesnitt, innså vi raskt at DOM er dårlig egnet til å jobbe med dynamiske brukergrensesnitt. Nesten umiddelbart ble en analog av Virtual DOM implementert for å optimalisere arbeidet med brukergrensesnittet. Under hendelsesbehandling lagres alle DOM-endringer i minnet, og bare når alle operasjoner er fullført, blir de akkumulerte endringene brukt på DOM-treet.

Optimalisering av nettklienten

For å få nettklienten vår til å fungere raskere, prøver vi å bruke standard nettleserfunksjoner (CSS, etc.) maksimalt. Dermed blir skjemakommandopanelet (plassert på nesten alle former for applikasjonen) gjengis utelukkende ved bruk av nettleserverktøy, ved bruk av dynamisk layout basert på CSS.

Om 1C-webklienten

Testing

For funksjons- og ytelsestesting bruker vi et proprietært verktøy (skrevet i Java og C++), samt en pakke med tester bygget på toppen av Selen.

Verktøyet vårt er universelt - det lar deg teste nesten alle program med vinduer, og er derfor egnet for å teste både en tynnklient og en nettklient. Verktøyet registrerer handlingene til brukeren som lanserte 1C-applikasjonsløsningen i en skriptfil. Samtidig tas bilder av arbeidsområdet på skjermen – standarder – opp. Ved overvåking av nye versjoner av nettklienten spilles skript uten brukermedvirkning. I tilfeller der skjermbildet ikke stemmer overens med referansen på noe trinn, anses testen som mislykket, hvoretter en kvalitetsspesialist gjennomfører en undersøkelse for å avgjøre om dette er en feil eller en planlagt endring i oppførselen til systemet. Ved planlagt atferd erstattes standardene automatisk med nye.

Verktøyet måler også applikasjonsytelse med en nøyaktighet på opptil 25 millisekunder. I noen tilfeller løkker vi deler av skriptet (for eksempel ved å gjenta ordreoppføringen flere ganger) for å analysere forringelsen av utførelsestiden over tid. Resultatene av alle målinger registreres i en logg for analyse.

Om 1C-webklienten
Vårt testverktøy og applikasjon under testing

Vårt verktøy og selen utfyller hverandre; for eksempel, hvis en knapp på en av skjermene har endret plassering, kan det hende at Selenium ikke sporer dette, men verktøyet vårt vil merke det, fordi gjør en piksel-for-piksel sammenligning av skjermbildet med standarden. Verktøyet er også i stand til å spore problemer med å behandle input fra tastaturet eller musen, siden det er akkurat dette det gjengir.

Tester på begge verktøyene (vårt og Selenium) kjører typiske arbeidsscenarier fra våre applikasjonsløsninger. Tester lanseres automatisk etter den daglige byggingen av 1C:Enterprise-plattformen. Hvis skriptene er tregere (sammenlignet med forrige versjon), undersøker og løser vi årsaken til nedgangen. Kriteriet vårt er enkelt - den nye konstruksjonen skal ikke fungere tregere enn den forrige.

Utviklere bruker forskjellige verktøy for å undersøke saktehendelser; hovedsakelig brukt Dynatrace AJAX Edition produksjonsselskap DynaTrace. Logger over utførelsen av den problematiske operasjonen på forrige og nye bygg registreres, deretter analyseres loggene. Samtidig kan det hende at utførelsestiden for enkeltoperasjoner (i millisekunder) ikke er en avgjørende faktor - tjenesteprosesser som søppelinnsamling startes med jevne mellomrom i nettleseren, de kan overlappe med utførelsestiden for funksjoner og forvrenge bildet. Mer relevante parametere i dette tilfellet vil være antall utførte JavaScript-instruksjoner, antall atomoperasjoner på DOM, etc. Hvis antall instruksjoner/operasjoner i samme script har økt i en ny versjon, betyr dette nesten alltid et ytelsesfall som må korrigeres.

En av årsakene til nedgangen i ytelse kan også være at Google Closure Compiler av en eller annen grunn ikke var i stand til å utføre innebygd erstatning av funksjonen (for eksempel fordi funksjonen er rekursiv eller virtuell). I dette tilfellet prøver vi å rette opp situasjonen ved å omskrive kildekoden.

Nettleserutvidelser

Når en applikasjonsløsning trenger funksjonalitet som ikke er tilgjengelig i JavaScript, bruker vi nettleserutvidelser:

Våre utvidelser består av to deler. Den første delen er det som kalles en nettleserutvidelse (vanligvis utvidelser for Chrome og Firefox skrevet i JavaScript), som samhandler med den andre delen – en binær utvidelse som implementerer funksjonaliteten vi trenger. Det skal nevnes at vi skriver 3 versjoner av binære utvidelser - for Windows, Linux og MacOS. Den binære utvidelsen leveres som en del av 1C:Enterprise-plattformen og er plassert på 1C-applikasjonsserveren. Når den ringes opp for første gang fra en nettklient, lastes den ned til klientdatamaskinen og installeres i nettleseren.

Når de kjører i Safari, bruker utvidelsene våre NPAPI; når de kjøres i Internet Explorer, bruker de ActiveX-teknologi. Microsoft Edge støtter ikke utvidelser ennå, så nettklienten i den fungerer med begrensninger.

Videre utvikling

En av oppgavene for webklientutviklingsteamet er videreutvikling av funksjonalitet. Funksjonaliteten til nettklienten skal være identisk med funksjonaliteten til den tynne klienten; all ny funksjonalitet implementeres samtidig i både tynn- og nettklienten.

Andre oppgaver inkluderer utvikling av arkitekturen, refaktorisering, forbedring av ytelse og pålitelighet. For eksempel er en av retningene videre bevegelse mot en asynkron arbeidsmodell. Noe av funksjonaliteten til webklienten er for tiden bygget på en synkron modell for interaksjon med serveren. Den asynkrone modellen blir nå mer relevant i nettlesere (og ikke bare i nettlesere), og dette tvinger oss til å modifisere nettklienten ved å erstatte synkrone anrop med asynkrone (og refaktorere koden deretter). Den gradvise overgangen til en asynkron modell forklares med behovet for å støtte utgitte løsninger og deres gradvise tilpasning.

Kilde: www.habr.com

Legg til en kommentar