O webovém klientovi 1C

Jednou z příjemných vlastností technologie 1C:Enterprise je, že aplikační řešení vyvinuté pomocí technologie spravovaných formulářů lze spustit jak v tenkém (spustitelném) klientovi pro Windows, Linux, MacOS X, tak jako webový klient pro 5 prohlížečů – Chrome, Internet Explorer, Firefox, Safari, Edge a to vše beze změny zdrojového kódu aplikace. Navíc navenek aplikace v tenkém klientovi a v prohlížeči funguje a vypadá téměř identicky.
Najděte 10 rozdílů (2 obrázky pod řezem):

Okno tenkého klienta v systému Linux:

O webovém klientovi 1C

Stejné okno ve webovém klientovi (v prohlížeči Chrome):

O webovém klientovi 1C

Proč jsme vytvořili webového klienta? Poněkud pateticky řečeno, čas nám takový úkol uložil. Práce přes internet je již dlouho nezbytným předpokladem pro podnikové aplikace. Nejprve jsme pro našeho tenkého klienta přidali možnost pracovat přes internet (někteří naši konkurenti se nad tím mimochodem zastavili, jiní naopak tenkého klienta opustili a omezili se na implementaci webového klienta). Rozhodli jsme se dát našim uživatelům možnost vybrat si klientskou variantu, která jim nejlépe vyhovuje.

O webovém klientovi 1C

Přidání webových funkcí do tenkého klienta byl velký projekt s kompletní změnou v architektuře klient-server. Vytvoření webového klienta je zcela nový projekt, který začíná od nuly.

Formulace problému

Požadavky projektu: webový klient musí udělat totéž co tenký klient, konkrétně:

  1. Zobrazit uživatelské rozhraní
  2. Spusťte klientský kód napsaný v jazyce 1C

Uživatelské rozhraní v 1C je popsáno ve vizuálním editoru, ale deklarativně, bez uspořádání prvků pixel po pixelu; Používají se asi tři desítky typů prvků rozhraní - tlačítka, vstupní pole (textové, číselné, datum/čas), seznamy, tabulky, grafy atd.

Klientský kód v jazyce 1C může obsahovat volání serveru, práci s místními zdroji (soubory atd.), tisk a mnoho dalšího.

Tenký klient (při práci přes web) i webový klient používají ke komunikaci s aplikačním serverem 1C stejnou sadu webových služeb. Klientské implementace jsou samozřejmě různé – tenký klient je napsán v C++, webový klient je napsán v JavaScriptu.

Trocha historie

Projekt webového klienta začal v roce 2006 s týmem (v průměru) 5 lidí. V určitých fázích projektu byli vývojáři zapojeni do implementace konkrétních funkcí (tabulkový dokument, diagramy atd.); zpravidla se jednalo o tytéž vývojáře, kteří tuto funkcionalitu provedli v tenkém klientovi. Tito. vývojáři přepsali komponenty v JavaScriptu, které dříve vytvořili v C++.

Od samého začátku jsme odmítli myšlenku jakékoli automatické (i částečné) konverze kódu tenkého klienta C++ na webového klienta JavaScript kvůli velkým koncepčním rozdílům mezi těmito dvěma jazyky; webový klient byl napsán v JavaScriptu od začátku.

V prvních iteracích projektu webový klient převáděl klientský kód ve vestavěném jazyce 1C přímo do JavaScriptu. Tenký klient se chová jinak – kód ve vestavěném jazyce 1C je zkompilován do bajtkódu a následně je tento bajtkód interpretován na klientovi. Následně to začal dělat i webový klient – ​​zaprvé zvýšil výkon a zadruhé umožnil sjednotit architekturu tenkého a webového klienta.

První verze platformy 1C:Enterprise s podporou webového klienta byla vydána v roce 2009. Webový klient v té době podporoval 2 prohlížeče - Internet Explorer a Firefox. Původní plány počítaly s podporou Opery, ale kvůli tehdejším nepřekonatelným problémům s obsluhou zavírání aplikace v Opeře (nebylo možné se 100% jistotou sledovat, že se aplikace zavírá, a v tu chvíli provést odpojení od aplikační server 1C) z těchto plánů musel být opuštěn.

Struktura projektu

Platforma 1C:Enterprise má celkem 4 projekty napsané v JavaScriptu:

  1. WebTools – sdílené knihovny používané jinými projekty (zahrnujeme také Knihovna uzavření Google).
  2. Ovládací prvek Formátovaný dokument (implementováno v JavaScriptu v tenkém i webovém klientovi)
  3. Ovládací prvek Планировщик (implementováno v JavaScriptu v tenkém i webovém klientovi)
  4. Webový klient

Struktura každého projektu se podobá struktuře Java projektů (nebo projektů .NET – podle toho, co je bližší); Máme jmenné prostory a každý jmenný prostor je v samostatné složce. Uvnitř složky jsou soubory a třídy jmenného prostoru. V projektu webového klienta je asi 1000 souborů.

Strukturálně je webový klient z velké části rozdělen do následujících subsystémů:

  • Rozhraní spravované klientské aplikace
    • Obecné rozhraní aplikace (systémová menu, panely)
    • Rozhraní spravovaných formulářů zahrnující mimo jiné cca 30 ovládacích prvků (tlačítka, různé typy vstupních polí - textové, číselné, datum/čas atd., tabulky, seznamy, grafy atd.)

  • Objektový model dostupný vývojářům na klientovi (celkem přes 400 typů: objektový model spravovaného rozhraní, nastavení rozložení dat, podmíněný styl atd.)
  • Interpret vestavěného jazyka 1C
  • Rozšíření prohlížeče (používá se pro funkce, které JavaScript nepodporuje)
    • Práce s kryptografií
    • Práce se soubory
    • Technologie externích komponent, umožňující jejich použití v tenkých i webových klientech

Vývojové funkce

Implementovat vše výše uvedené do JavaScriptu není jednoduché. Možná je webový klient 1C jednou z největších aplikací na straně klienta napsaných v JavaScriptu – asi 450.000 XNUMX řádků. V kódu webového klienta aktivně využíváme objektově orientovaný přístup, který zjednodušuje práci s tak velkým projektem.

Abychom minimalizovali velikost klientského kódu, použili jsme nejprve vlastní obfuscator a počínaje verzí platformy 8.3.6 (říjen 2014) jsme začali používat Google Closure Compiler. Efekt použití v číslech – velikost rámce webového klienta po zmatku:

  • Vlastní obfuskátor – 1556 kb
  • Google Closure Compiler – 1073 kb

Použití Google Closure Compiler nám pomohlo zlepšit výkon webového klienta o 30 % ve srovnání s naším vlastním obfuscátorem. Kromě toho se množství paměti spotřebované aplikací snížilo o 15–25 % (v závislosti na prohlížeči).

Google Closure Compiler velmi dobře pracuje s objektově orientovaným kódem, takže jeho efektivita pro webového klienta je co nejvyšší. Closure Compiler pro nás dělá několik dobrých věcí:

  • Statická kontrola typu ve fázi sestavení projektu (zajišťuje, že kód pokryjeme anotacemi JSDoc). Výsledkem je statické psaní, na úrovni velmi blízké psaní v C++. To pomáhá zachytit poměrně velké procento chyb ve fázi kompilace projektu.
  • Snížení velikosti kódu prostřednictvím zmatku
  • Řada optimalizací prováděného kódu, například:
    • vložené substituce funkcí. Volání funkce v JavaScriptu je poměrně nákladná operace a inline substituce často používaných malých metod výrazně zrychlují kód.
    • Počítání konstant v době kompilace. Pokud výraz závisí na konstantě, dosadí se do něj skutečná hodnota konstanty

WebStorm používáme jako vývojové prostředí našeho webového klienta.

Pro analýzu kódu používáme soundQube, kde integrujeme analyzátory statického kódu. Pomocí analyzátorů sledujeme zhoršování kvality zdrojového kódu JavaScriptu a snažíme se mu předcházet.

O webovém klientovi 1C

Jaké problémy jsme řešili/řešíme?

Při realizaci projektu jsme narazili na řadu zajímavých problémů, které jsme museli řešit.

Výměna dat se serverem a mezi okny

Existují situace, kdy zatemnění zdrojového kódu může narušit chod systému. Kód externí ke spustitelnému kódu webového klienta může mít kvůli zamlžení názvy funkcí a parametrů, které se liší od těch, které očekává náš spustitelný kód. Externí kód pro nás je:

  • Kód přicházející ze serveru ve formě datových struktur
  • Kód pro jiné okno aplikace

Abychom se vyhnuli zmatkům při interakci se serverem, používáme značku @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;
}

A abychom předešli zmatkům při interakci s jinými okny, používáme tzv. exportovaná rozhraní (rozhraní, ve kterých se exportují všechny metody).

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

Virtual DOM jsme používali předtím, než se stal mainstreamem)

Stejně jako všichni vývojáři, kteří se zabývají složitými webovými uživatelskými rozhraními, jsme si rychle uvědomili, že DOM není vhodný pro práci s dynamickými uživatelskými rozhraními. Téměř okamžitě byl implementován analog Virtual DOM pro optimalizaci práce s uživatelským rozhraním. Během zpracování událostí se všechny změny DOM ukládají do paměti a teprve po dokončení všech operací se nashromážděné změny použijí na strom DOM.

Optimalizace webového klienta

Aby náš webový klient fungoval rychleji, snažíme se maximálně využít možnosti standardního prohlížeče (CSS apod.). Panel příkazů formuláře (umístěný téměř na každém formuláři aplikace) je tedy vykreslován výhradně pomocí nástrojů prohlížeče s použitím dynamického rozložení založeného na CSS.

O webovém klientovi 1C

Testování

Pro testování funkčnosti a výkonu používáme proprietární nástroj (napsaný v Javě a C++) a také sadu testů postavenou na Selen.

Náš nástroj je univerzální – umožňuje testovat téměř jakýkoli okenní program, a proto je vhodný pro testování tenkého i webového klienta. Nástroj zaznamenává akce uživatele, který spustil řešení aplikace 1C, do souboru skriptu. Současně jsou zaznamenávány obrazy pracovní oblasti obrazovky - standardy. Při sledování nových verzí webového klienta se skripty přehrávají bez účasti uživatele. V případech, kdy snímek obrazovky v žádném kroku neodpovídá referenčnímu, je test považován za neúspěšný, načež odborník na kvalitu provede šetření, aby zjistil, zda se jedná o chybu nebo plánovanou změnu chování systému. V případě plánovaného chování jsou standardy automaticky nahrazeny novými.

Nástroj také měří výkon aplikace s přesností až 25 milisekund. V některých případech zacyklíme části skriptu (například několikrát opakujeme zadání objednávky), abychom analyzovali degradaci doby provádění v průběhu času. Výsledky všech měření se zapisují do protokolu pro analýzu.

O webovém klientovi 1C
Náš testovací nástroj a aplikace jsou testovány

Náš nástroj a Selenium se vzájemně doplňují; pokud například některé tlačítko na jedné z obrazovek změnilo své umístění, Selenium to nemusí sledovat, ale náš nástroj si toho všimne, protože provede porovnání snímku obrazovky se standardem pixel po pixelu. Nástroj je také schopen sledovat problémy se zpracováním vstupu z klávesnice nebo myši, protože přesně to reprodukuje.

Testy obou nástrojů (našeho a Selenium) spouštějí typické pracovní scénáře z našich aplikačních řešení. Testy jsou automaticky spuštěny po každodenním sestavení platformy 1C:Enterprise. Pokud jsou skripty pomalejší (ve srovnání s předchozím sestavením), vyšetřujeme a řešíme příčinu zpomalení. Naše kritérium je jednoduché – nová sestava by neměla fungovat pomaleji než ta předchozí.

Vývojáři používají různé nástroje k vyšetřování incidentů zpomalení; hlavně používané Dynatrace AJAX Edition firemní produkce DynaTrace. Zaznamenávají se protokoly o provedení problematické operace na předchozích a nových sestaveních, poté jsou protokoly analyzovány. Doba provádění jednotlivých operací (v milisekundách) přitom nemusí být rozhodujícím faktorem - servisní procesy typu garbage collection jsou v prohlížeči pravidelně spouštěny, mohou se překrývat s dobou provádění funkcí a zkreslovat obraz. Relevantnějšími parametry by v tomto případě byl počet provedených instrukcí JavaScriptu, počet atomických operací na DOM atd. Pokud se v nové verzi zvýšil počet instrukcí/operací ve stejném skriptu, znamená to téměř vždy pokles výkonu, který je třeba opravit.

Jedním z důvodů poklesu výkonu může být také to, že Google Closure Compiler z nějakého důvodu nebyl schopen provést inline náhradu funkce (například protože je funkce rekurzivní nebo virtuální). V tomto případě se snažíme situaci napravit přepsáním zdrojového kódu.

Rozšíření prohlížeče

Pokud aplikační řešení potřebuje funkce, které nejsou dostupné v JavaScriptu, používáme rozšíření prohlížeče:

Naše rozšíření se skládají ze dvou částí. První částí je to, čemu se říká rozšíření prohlížeče (obvykle rozšíření pro Chrome a Firefox napsaná v JavaScriptu), která interagují s druhou částí – binárním rozšířením, které implementuje funkcionalitu, kterou potřebujeme. Je třeba zmínit, že píšeme 3 verze binárních rozšíření – pro Windows, Linux a MacOS. Binární rozšíření je dodáváno jako součást platformy 1C:Enterprise a je umístěno na aplikačním serveru 1C. Při prvním volání z webového klienta se stáhne do klientského počítače a nainstaluje se do prohlížeče.

Když běží v Safari, naše rozšíření používají NPAPI, když běží v Internet Exploreru, používají technologii ActiveX. Microsoft hran zatím nepodporuje rozšíření, takže webový klient v něm funguje s omezeními.

Další vývoj

Jedním z úkolů vývojového týmu webového klienta je další rozvoj funkcionality. Funkčnost webového klienta by měla být shodná s funkčností tenkého klienta, všechny nové funkcionality jsou implementovány současně do tenkého i webového klienta.

Mezi další úkoly patří vývoj architektury, refaktorizace, zlepšování výkonu a spolehlivosti. Jedním ze směrů je například další pohyb směrem k asynchronnímu pracovnímu modelu. Některé funkce webového klienta jsou v současné době postaveny na synchronním modelu interakce se serverem. Asynchronní model je nyní v prohlížečích (a nejen v prohlížečích) relevantnější, a to nás nutí upravit webového klienta nahrazením synchronních volání asynchronními (a odpovídajícím způsobem refaktorovat kód). Postupný přechod na asynchronní model je vysvětlován potřebou podpory uvolněných řešení a jejich postupnou adaptací.

Zdroj: www.habr.com

Přidat komentář