Om 1C-webbklienten

En av de trevliga funktionerna med 1C:Enterprise-teknologin är att applikationslösningen, utvecklad med teknik för hanterade formulär, kan lanseras både i en tunn (körbar) klient för Windows, Linux, MacOS X, och som en webbklient för 5 webbläsare - Chrome, Internet Explorer, Firefox, Safari, Edge och allt detta utan att ändra applikationens källkod. Dessutom externt fungerar och ser applikationen i den tunna klienten och i webbläsaren nästan identisk ut.
Hitta 10 skillnader (2 bilder under snittet):

Tunt klientfönster på Linux:

Om 1C-webbklienten

Samma fönster i webbklienten (i Chrome-webbläsaren):

Om 1C-webbklienten

Varför skapade vi en webbklient? För att uttrycka det lite patetiskt, tiden har satt en sådan uppgift för oss. Att arbeta över Internet har länge varit en förutsättning för affärsapplikationer. Först lade vi till möjligheten att arbeta via Internet för vår tunna klient (några av våra konkurrenter stannade förresten vid detta, andra tvärtom övergav den tunna klienten och begränsade sig till att implementera en webbklient). Vi bestämde oss för att ge våra användare möjlighet att välja det klientalternativ som passar dem bäst.

Om 1C-webbklienten

Att lägga till webbaserade funktioner till den tunna klienten var ett stort projekt med en fullständig förändring av klient-server-arkitekturen. Att skapa en webbklient är ett helt nytt projekt som börjar från början.

Problem uttalande

Så projektkraven: webbklienten måste göra samma sak som den tunna klienten, nämligen:

  1. Visa användargränssnitt
  2. Kör klientkod skriven på 1C-språk

Användargränssnittet i 1C beskrivs i en visuell editor, men deklarativt, utan pixel-för-pixel-arrangemang av element; Cirka tre dussin typer av gränssnittselement används - knappar, inmatningsfält (text, siffror, datum/tid), listor, tabeller, grafer, etc.

Klientkod på 1C-språket kan innehålla serveranrop, arbete med lokala resurser (filer, etc.), utskrift och mycket mer.

Både den tunna klienten (när man arbetar via webben) och webbklienten använder samma uppsättning webbtjänster för att kommunicera med 1C-applikationsservern. Klientimplementeringarna är naturligtvis olika - den tunna klienten är skriven i C++, webbklienten är skriven i JavaScript.

Lite historia

Webbklientprojektet startade 2006, med ett team på (i genomsnitt) 5 personer. I vissa skeden av projektet involverades utvecklare för att implementera specifik funktionalitet (kalkylbladsdokument, diagram, etc.); som regel var det samma utvecklare som gjorde den här funktionen i den tunna klienten. De där. utvecklare skrev om komponenter i JavaScript som de tidigare hade skapat i C++.

Redan från början avvisade vi idén om varje automatisk (även delvis) konvertering av C++-tunnklientkod till JavaScript-webklient på grund av de starka konceptuella skillnaderna mellan de två språken; webbklienten skrevs i JavaScript från grunden.

I de första iterationerna av projektet konverterade webbklienten klientkoden i det inbyggda 1C-språket direkt till JavaScript. Den tunna klienten agerar annorlunda - koden i det inbyggda 1C-språket kompileras till bytekod, och sedan tolkas denna bytekod på klienten. Därefter började webbklienten göra detsamma - för det första gav det en prestandavinst, och för det andra gjorde det det möjligt att förena arkitekturen för de tunna klienterna och webbklienterna.

Den första versionen av 1C:Enterprise-plattformen med webbklientstöd släpptes 2009. Webklienten vid den tiden stödde 2 webbläsare - Internet Explorer och Firefox. De ursprungliga planerna inkluderade stöd för Opera, men på grund av oöverstigliga problem vid den tiden med applikationens stängningshanterare i Opera (det var inte möjligt att spåra med 100% säkerhet att applikationen stängdes, och i det ögonblicket utföra frånkopplingsproceduren från 1C-applikationsservern) från dessa planer måste överges.

Projektets struktur

Totalt har 1C:Enterprise-plattformen 4 projekt skrivna i JavaScript:

  1. WebTools – delade bibliotek som används av andra projekt (vi inkluderar även Googles stängningsbibliotek).
  2. Kontrollelement Formaterat dokument (implementerat i JavaScript i både den tunna klienten och webbklienten)
  3. Kontrollelement Schemaläggare (implementerat i JavaScript i både den tunna klienten och webbklienten)
  4. Webbklient

Strukturen för varje projekt liknar strukturen för Java-projekt (eller .NET-projekt - beroende på vilket som är närmast); Vi har namnutrymmen och varje namnområde finns i en separat mapp. Inuti mappen finns filer och namnområdesklasser. Det finns cirka 1000 filer i webbklientprojektet.

Strukturellt är webbklienten till stor del uppdelad i följande delsystem:

  • Hanterat klientapplikationsgränssnitt
    • Allmänt applikationsgränssnitt (systemmenyer, paneler)
    • Gränssnitt för hanterade formulär, inklusive bland annat ett 30-tal kontroller (knappar, olika typer av inmatningsfält - text, numerisk, datum/tid, etc., tabeller, listor, grafer, etc.)

  • Objektmodell tillgänglig för utvecklare på klienten (över 400 typer totalt: objektmodell för hanterat gränssnitt, inställningar för datalayout, villkorlig stil, etc.)
  • Tolk av det inbyggda 1C-språket
  • Webbläsartillägg (används för funktioner som inte stöds i JavaScript)
    • Jobbar med kryptografi
    • Arbeta med filer
    • Teknik för externa komponenter, vilket gör att de kan användas i både tunna klienter och webbklienter

Utvecklingsfunktioner

Att implementera allt ovan i JavaScript är inte lätt. Kanske är 1C-webbklienten en av de största klientsidans applikationer skrivna i JavaScript - cirka 450.000 XNUMX rader. Vi använder aktivt ett objektorienterat förhållningssätt i webbklientkoden, vilket förenklar arbetet med ett så stort projekt.

För att minimera storleken på klientkoden använde vi först vår egen obfuscator, och från och med plattformsversion 8.3.6 (oktober 2014) började vi använda Google Closure Compiler. Effekten av användning i siffror – storleken på webbklientramverket efter förvirring:

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

Att använda Google Closure Compiler hjälpte oss att förbättra prestandan för webbklienten med 30 % jämfört med vår egen obfuscator. Dessutom har mängden minne som konsumeras av applikationen minskat med 15-25 % (beroende på webbläsare).

Google Closure Compiler fungerar mycket bra med objektorienterad kod, så dess effektivitet för webbklienten är så hög som möjligt. Closure Compiler gör några bra saker för oss:

  • Statisk typkontroll i projektets byggskede (säkerställer att vi täcker koden med JSDoc-kommentarer). Resultatet är statisk typning, mycket nära att skriva i C++ i nivå. Detta hjälper till att fånga upp en ganska stor procentandel av fel i projektsammanställningsstadiet.
  • Minska kodstorleken genom förvirring
  • Ett antal optimeringar av den körda koden, till exempel, såsom:
    • inline funktionsersättningar. Att anropa en funktion i JavaScript är en ganska dyr operation, och inline-ersättningar av ofta använda små metoder påskyndar koden avsevärt.
    • Räkna konstanter vid kompilering. Om ett uttryck beror på en konstant, kommer det faktiska värdet av konstanten att ersättas i det

Vi använder WebStorm som vår webbklientutvecklingsmiljö.

För kodanalys använder vi soundQube, där vi integrerar statiska kodanalysatorer. Med hjälp av analysatorer övervakar vi försämringen av kvaliteten på JavaScript-källkoden och försöker förhindra det.

Om 1C-webbklienten

Vilka problem löste/löser vi?

Under genomförandet av projektet stötte vi på ett antal intressanta problem som vi var tvungna att lösa.

Utbyta data med servern och mellan fönster

Det finns situationer där förvirring av källkoden kan störa systemets funktion. Kod utanför webbklientens körbara kod kan på grund av förvirring ha funktions- och parameternamn som skiljer sig från de som vår körbara kod förväntar sig. Den externa koden för oss är:

  • Kod som kommer från servern i form av datastrukturer
  • Kod för ett annat programfönster

För att undvika förvirring när vi interagerar med servern använder vi taggen @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;
}

Och för att undvika förvirring när vi interagerar med andra fönster använder vi så kallade exporterade gränssnitt (gränssnitt där alla metoder exporteras).

/**
 * Экспортируемый интерфейс контрола 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 använde Virtual DOM innan det blev mainstream)

Liksom alla utvecklare som sysslar med komplexa webbgränssnitt, insåg vi snabbt att DOM är dåligt lämpat för att arbeta med dynamiska användargränssnitt. Nästan omedelbart implementerades en analog av Virtual DOM för att optimera arbetet med användargränssnittet. Under händelsebearbetning lagras alla DOM-ändringar i minnet och endast när alla operationer är slutförda tillämpas de ackumulerade ändringarna på DOM-trädet.

Optimera webbklienten

För att få vår webbklient att fungera snabbare försöker vi använda standardfunktionerna i webbläsaren (CSS, etc.) maximalt. Således renderas formulärets kommandopanel (som finns på nästan varje form av applikationen) uteslutande med webbläsarverktyg, med dynamisk layout baserad på CSS.

Om 1C-webbklienten

testning

För funktions- och prestandatestning använder vi ett proprietärt verktyg (skrivet i Java och C++), samt en uppsättning tester som är byggda ovanpå Selen.

Vårt verktyg är universellt - det låter dig testa nästan alla fönsterprogram och är därför lämpligt för att testa både en tunn klient och en webbklient. Verktyget registrerar handlingar av användaren som lanserade 1C-applikationslösningen i en skriptfil. Samtidigt spelas bilder av skärmens arbetsområde - standarder - in. Vid övervakning av nya versioner av webbklienten spelas skript utan användarmedverkan. I de fall skärmdumpen inte stämmer överens med referensen i något steg anses testet vara misslyckat, varefter en kvalitetsspecialist gör en utredning för att fastställa om detta är ett fel eller en planerad förändring av systemets beteende. Vid planerat beteende ersätts standarderna automatiskt med nya.

Verktyget mäter också applikationsprestanda med en noggrannhet på upp till 25 millisekunder. I vissa fall slingrar vi delar av skriptet (till exempel genom att upprepa orderinmatningen flera gånger) för att analysera försämringen av exekveringstiden över tid. Resultaten av alla mätningar registreras i en logg för analys.

Om 1C-webbklienten
Vårt testverktyg och applikation under test

Vårt verktyg och Selen kompletterar varandra; till exempel, om någon knapp på en av skärmarna har ändrat sin plats, kanske Selenium inte spårar detta, men vårt verktyg kommer att märka det, eftersom gör en pixel-för-pixel-jämförelse av skärmdumpen med standarden. Verktyget kan också spåra problem med att bearbeta indata från tangentbordet eller musen, eftersom det är exakt vad det återger.

Tester på båda verktygen (vårt och Selenium) kör typiska arbetsscenarier från våra applikationslösningar. Tester startas automatiskt efter den dagliga uppbyggnaden av 1C:Enterprise-plattformen. Om skript är långsammare (jämfört med föregående version) undersöker vi och löser orsaken till nedgången. Vårt kriterium är enkelt - den nya konstruktionen ska inte fungera långsammare än den tidigare.

Utvecklare använder olika verktyg för att undersöka avmattningsincidenter; huvudsakligen används Dynatrace AJAX Edition tillverkningsföretag DynaTrace. Loggar över utförandet av den problematiska operationen på tidigare och nya byggnader registreras, sedan analyseras loggarna. Samtidigt kan exekveringstiden för enstaka operationer (i millisekunder) inte vara en avgörande faktor - tjänsteprocesser som skräphämtning startas med jämna mellanrum i webbläsaren, de kan överlappa med exekveringstiden för funktioner och förvränga bilden. Mer relevanta parametrar i detta fall skulle vara antalet JavaScript-instruktioner som körs, antalet atomära operationer på DOM, etc. Om antalet instruktioner/operationer i samma script har ökat i en ny version innebär detta nästan alltid en prestandasänkning som behöver korrigeras.

En av anledningarna till prestandaminskningen kan också vara att Google Closure Compiler av någon anledning inte kunde utföra inline-ersättning av funktionen (till exempel eftersom funktionen är rekursiv eller virtuell). I det här fallet försöker vi korrigera situationen genom att skriva om källkoden.

Webbläsartillägg

När en applikationslösning behöver funktionalitet som inte är tillgänglig i JavaScript använder vi webbläsartillägg:

Våra förlängningar består av två delar. Den första delen är vad som kallas webbläsartillägg (vanligtvis tillägg för Chrome och Firefox skrivna i JavaScript), som interagerar med den andra delen – ett binärt tillägg som implementerar den funktionalitet vi behöver. Det bör nämnas att vi skriver 3 versioner av binära tillägg - för Windows, Linux och MacOS. Det binära tillägget tillhandahålls som en del av 1C:Enterprise-plattformen och finns på 1C-applikationsservern. När den anropas för första gången från en webbklient, laddas den ner till klientdatorn och installeras i webbläsaren.

När de körs i Safari använder våra tillägg NPAPI, när de körs i Internet Explorer använder de ActiveX-teknik. Microsoft Edge stöder ännu inte tillägg, så webbklienten i den fungerar med begränsningar.

Ytterligare utveckling

En av uppgifterna för webbklientutvecklingsteamet är vidareutveckling av funktionalitet. Funktionaliteten hos webbklienten bör vara identisk med funktionaliteten hos den tunna klienten, all ny funktionalitet implementeras samtidigt i både den tunna klienten och webbklienten.

Andra uppgifter inkluderar att utveckla arkitekturen, omstrukturera, förbättra prestanda och tillförlitlighet. Till exempel är en av riktningarna ytterligare förflyttning mot en asynkron arbetsmodell. En del av funktionaliteten hos webbklienten bygger för närvarande på en synkron modell för interaktion med servern. Den asynkrona modellen blir nu mer relevant i webbläsare (och inte bara i webbläsare), och detta tvingar oss att modifiera webbklienten genom att ersätta synkrona anrop med asynkrona (och omstrukturera koden därefter). Den gradvisa övergången till en asynkron modell förklaras av behovet av att stödja släppta lösningar och deras gradvisa anpassning.

Källa: will.com

Lägg en kommentar