O webovém klientu 1C

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

Okno tenkého klienta na Linuxu:

O webovém klientu 1C

Tentýž okno ve webovém klientu (v prohlížeči Chrome):

O webovém klientu 1C

Proč jsme vytvořili webového klienta? Řečeno trochu vznešeně, takový úkol před nás postavil čas. Již dlouho se práce přes internet stala nezbytnou podmínkou pro obchodní aplikace. Zpočátku jsme přidali možnost práce přes internet pro našeho tenkého klienta (někteří naši konkurenti, mimochodem, na tomto i skončili; jiní, naopak, se vzdali tenkého klienta a omezili se pouze na realizaci webového klienta). My jsme se však rozhodli poskytnout našim uživatelům možnost vybrat si ten typ klienta, který jim vyhovuje nejvíce.

O webovém klientu 1C

Přidání možnosti práce přes internet pro tenkého klienta bylo velkým projektem s kompletní změnou architektury klient-server interakce. Vytvoření webového klienta – to je úplně nový projekt, který začínal od nuly.

Formulace úkolu

Takže, požadavky na projekt: webový klient musí dělat to samé, co tenký klient, a to konkrétně:

  1. Zobrazit uživatelské rozhraní
  2. Spouštět klientský kód napsaný v jazyce 1C

Uživatelské rozhraní v 1C je popsáno ve vizuálním editoru, ale deklarativně, bez pixelového uspořádání prvků; používá se kolem třiceti typů prvků rozhraní – tlačítka, vstupní pole (textová, číselná, datum/čas), seznamy, tabulky, grafy atd.

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

Jak tenký klient (při práci přes web), tak webový klient používají stejnou sadu webových služeb pro komunikaci se serverem aplikací 1C. Implementace u klientů je samozřejmě různá – tenký klient je napsán v C++, webový klient – v JavaScriptu.

Trocha historie

Projekt vytvoření webového klienta začal v roce 2006, průměrně se na něm podílela pětice lidí. V jednotlivých fázích projektu byli najímáni vývojáři pro implementaci specifické funkčnosti (tabulkového dokumentu, diagramů atd.); obvykle to byli stejní vývojáři, kteří tuto funkčnost realizovali v tenkém klientu. Tedy vývojáři znovu napsali komponenty na JavaScript, které dříve vytvořili v C++.

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

V prvních iteracích projektu webový klient konvertoval klientský kód na vestavěném jazyce 1C přímo do JavaScriptu. Tenký klient to dělá jinak – kód na vestavěném jazyce 1C je kompilován do bajtkódu a poté je tento bajtkód interpretován na klientovi. V průběhu času to začal dělat i webový klient – jednak to přineslo zisk v výkonu, jednak to umožnilo unifikovat 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 tehdy podporoval 2 prohlížeče – Internet Explorer a Firefox. V původních plánech byla podpora prohlížeče Opera, ale kvůli nezdolatelným problémům s obsluhou uzavření aplikace v Opeře (nepodařilo se se 100% jistotou sledovat, kdy aplikace končí, a v tomto okamžiku provést proceduru odpojení od serveru aplikací 1C) bylo nutno od těchto plánů upustit.

Struktura projektu

V platformě 1C:Enterprise existují celkem 4 projekty napsané v JavaScriptu:

  1. WebTools – obecné knihovny používané ostatními projekty (sem zahrnujeme také Google Closure Library).
  2. Ovládací prvek FormátovanýDokument (implementován v JavaScriptu jak v tenkém klientu, tak ve webovém klientu)
  3. Ovládací prvek Plánovač (implementován v JavaScriptu jak v tenkém klientu, tak ve webovém klientu)
  4. Webový klient

Struktura každého projektu připomíná strukturu Java projektů (nebo .NET projektů – komu co vyhovuje); máme zde názvové prostory a každý názvový prostor je v samostatné složce. Uvnitř složky jsou soubory a třídy názvového prostoru. V projektu webového klienta je přibližně 1000 souborů.

Strukturně je webový klient přibližně rozdělen na následující subsystémy:

  • Spravované rozhraní klientské aplikace
    • Obecné rozhraní aplikace (systémová menu, panely)
    • Rozhraní řízených formulářů, obsahující přibližně 30 ovládacích prvků (tlačítka, různé typy vstupních polí – textové, číselné, datum/čas atd., tabulky, seznamy, grafy a podobně)

  • Objektový model dostupný vývojářům na klientské straně (celkem přes 400 typů: objektový model řízeného rozhraní, nastavení uspořádání dat, podmínkového formátování atd.)
  • Interpretátor vestavěného jazyka 1C
  • Prodloužení pro prohlížeče (používá se pro funkčnost, která není podporována v JavaScriptu)
    • Práce s kryptografií
    • Práce se soubory
    • Technologie externích komponent, umožňující jejich použití jak v tenkém, tak ve webovém klientovi

Specifika vývoje

Realizace všeho výše uvedeného v JavaScriptu není jednoduchá záležitost. Možná je webový klient 1C jednou z největších aplikací na straně klienta napsaných v JavaScriptu – kolem 450 000 řádků. Aktivně používáme v kódu webového klienta objektově orientovaný přístup, který usnadňuje práci s tak velkým projektem.

Abychom minimalizovali velikost klientského kódu, zpočátku jsme používali vlastní obfuscátor, a od verze platformy 8.3.6 (říjen 2014) jsme začali používat Google Closure Compiler. Efekt použití v číslech – velikost frameworku webového klienta po obfuskaci:

  • Vlastní obfuscátor – 1556 kB
  • Google Closure Compiler – 1073 kB

Použití Google Closure Compiler nám pomohlo zvýšit výkon webového klienta o 30 % ve srovnání s naším vlastním obfuscátorem. Kromě toho došlo k 15-25% (v závislosti na prohlížeči) snížení objemu paměti, kterou aplikace spotřebovává.

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

  • Statická kontrola typů při sestavení projektu (zajišťuje to, že pokrýváme kód anotacemi JSDoc). Výsledkem je statické typování, velmi blízké úrovni typování v C++. To pomáhá zachytit poměrně velké procento chyb ve fázi kompilace projektu.
  • Snížení velikosti kódu pomocí obfuskace
  • Řada optimalizací vykonávaného kódu, například takové jako:
    • Inline nahrazení funkcí. Zavolání funkce v JavaScriptu je dost náročná operace a inline nahrazení často používaných malých metod podstatně zrychluje běh kódu.
    • Počítání konstant v době kompilace. Pokud výraz závisí na konstantě, skutečná hodnota konstanty bude do něj vložena.

Jako vývojové prostředí webového klienta používáme WebStorm.

Pro analýzu kódu používáme SonarQube, kam integrujeme statické analyzátory kódu. Pomocí analyzátorů sledujeme degradaci kvality zdrojového kódu v JavaScriptu a snažíme se jí předejít.

O webovém klientu 1C

Jaké úkoly jsme řešili/řešíme

Během realizace projektu jsme se setkali s řadou zajímavých úkolů, které jsme museli řešit.

Výměna dat se serverem a mezi okny

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

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

Abychom se vyhnuli obfuskaci při interakci se serverem, používáme 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;
}

A aby se předešlo obfuskaci při interakci s jinými okny, používáme takzvané exportované rozhraní (rozhraní, kde jsou všechny metody exportovatelné).

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

Použili jsme Virtual DOM, než se stal populárním)

Jako všichni vývojáři, kteří se zabývají složitým webovým uživatelským rozhraním, jsme rychle pochopili, že DOM není příliš vhodný pro práci s dynamickým uživatelským rozhraním. Prakticky okamžitě byl realizován analog Virtual DOM pro optimalizaci práce s UI. Během zpracování události jsou všechna DOM změny ukládána do paměti a až po dokončení všech operací se akumulované změny použijí na DOM strom.

Optimalizace práce webového klienta

Aby náš webový klient fungoval rychleji, snažíme se naplno využít standardní možnosti prohlížeče (CSS atd.). Například, panel nástrojů formuláře (umístěný prakticky na každém formuláři aplikace) je vykreslován výhradně prostředky prohlížeče, s dynamickým designem na základě CSS.

O webovém klientu 1C

Testování

Pro funkční testování a testování výkonu používáme náš vlastní nástroj (napsaný v Javě a C++), stejně jako sadu testů založenou na Selenium.

Náš nástroj je univerzální – umožňuje testovat prakticky jakékoli desktopové aplikace, a proto je vhodný jak pro testování tenkého klienta, tak i webového klienta. Nástroj zaznamenává akce uživatele, který spustil aplikační řešení „1C“, do skriptového souboru. Zároveň se provádí záznam snímků pracovní plochy obrazovky – standardů. Při kontrole nových verzí webového klienta se scénáře přehrávají bez účasti uživatele. V případě, že se snímek obrazovky neshoduje s referentním na jakémkoli kroku, je test považován za neúspěšný, po čemž odborník na kvalitu provádí vyšetřování – zda se jedná o chybu nebo plánovanou změnu chování systému. V případě plánovaného chování se standardy automaticky nahrazují novými.

Nástroj také provádí měření výkonu aplikací s přesností až na 25 milisekund. V některých případech uzavíráme části scénáře (například několikrát opakujeme zadávání objednávky) pro analýzu degenerace doby zpracování časem. Výsledky všech měření se zaznamenávají do protokolu pro analýzu.

O webovém klientu 1C
Náš testovací nástroj a testovaná aplikace

Náš nástroj a Selenium se doplňují; například, pokud se nějaké tlačítko na jedné z obrazovek změnilo v umístění – Selenium to nemusí zjistit, ale náš nástroj si toho všimne, protože provádí pixelové porovnání snímku obrazovky s referencí. Nástroj také dokáže odhalit problémy s zpracováním vstupu z klávesnice nebo myši, protože je právě reprodukuje.

Testy na obou nástrojích (našem a Selenium) spouští standardní pracovní scénáře z našich aplikačních řešení. Testy se automaticky spouštějí po každodenní sestavě platformy „1C:Enterprise“. V případě zpomalení scénářů (ve srovnání s předchozí sestavou) provádíme vyšetřování a odstraňujeme příčinu zpomalení. Naše kritérium je jednoduché – nová sestava by měla fungovat nepomaleji než předchozí.

Pro vyšetřování incidentů zpomalení práce vývojáři používají různé nástroje; převážně se používá Dynatrace AJAX Edition výrobce společnosti DynaTrace. Provádí se záznam protokolů provádění problémové operace na předchozí a nové verzi, poté se protokoly analyzují. Přitom doba provádění jednotlivých operací (v milisekundách) nemusí být rozhodujícím faktorem – v prohlížeči se občas spouštějí obslužné procesy, jako je úklid paměti, které mohou ovlivnit dobu provádění funkcí a zkreslit obraz. Relevatnějšími parametry v tomto případě budou počet provedených instrukcí JavaScript, počet atomárních operací nad DOM atd. Pokud se počet instrukcí/operací ve stejném scénáři v nové verzi zvýšil – většinou to znamená pokles výkonu, který je třeba opravit.

Další příčinou poklesu výkonu může být skutečnost, že Google Closure Compiler z nějakého důvodu nebyl schopen provést inline nahrazení funkce (například protože je funkce rekurzivní nebo virtuální). V takovém případě se snažíme situaci napravit přepisem zdrojového kódu.

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

V případě, že aplikačnímu řešení chybí funkčnost, kterou JavaScript neposkytuje, používáme rozšíření prohlížečů:

Naše rozšíření se skládá ze dvou částí. První část – to, co se nazývá rozšíření prohlížeče (obvykle rozšíření napsaná v JavaScriptu pro Chrome a Firefox), která interaguje s druhou částí – binárním rozšířením, které implementuje požadovanou funkčnost. 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 nachází se na serveru aplikací 1C. Při prvním volání z webového klienta se načte na klientský počítač a nainstaluje do prohlížeče.

Při práci v Safari naše rozšíření využívají NPAPI, při práci v Internet Exploreru – technologii ActiveX. Microsoft Edge zatím nepodporuje rozšíření, takže webový klient v něm funguje s omezeními.

Další rozvoj

Jedna z úloh pro tým vývoje webového klienta spočívá v dalším rozvoji funkcionality. Funkcionalita webového klienta by měla být totožná s funkcionalitou tenkého klienta, veškerá nová funkcionalita je realizována současně jak pro tenký, tak pro webový klient.

Další úkoly zahrnují rozvoj architektury, refaktoring, zvyšování výkonnosti a spolehlivosti. Například jedním z směrů je další posun směrem k asynchronnímu modelu práce. Část funkcionality webového klienta je v současné době postavena na synchronním modelu interakce se serverem. Asynchronní model se nyní stává v prohlížečích (a nejen v prohlížečích) aktuálnější a to nás nutí modifikovat webového klienta nahrazením synchronních volání asynchronními (a odpovídajícím refaktoringem kódu). Postupný přechod k asynchronnímu modelu je dán nutností podpory vydaných řešení a jejich postupné adaptace.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster