Über den 1C-Webclient

Eine der angenehmen Eigenschaften der Technologie 1C:Unternehmen ist, dass die Anwendung, die mit Managed Forms entwickelt wurde, sowohl als dünner (ausführender) Client unter Windows, Linux, MacOS X als auch als Webclient in 5 Browsern – Chrome, Internet Explorer, Firefox, Safari, Edge – betrieben werden kann, und das alles ohne Änderungen am Quellcode der Anwendung. Darüber hinaus funktioniert die Anwendung im dünnen Client und im Browser praktisch identisch und sieht auch so aus.
Finden Sie 10 Unterschiede (unter dem Link 2 Bilder):

Fenster des dünnen Clients unter Linux:

Über den 1C-Webclient

Dasselbe Fenster im Webclient (im Browser Chrome):

Über den 1C-Webclient

Warum haben wir einen Webclient erstellt? Um es etwas pathetisch auszudrücken, hat uns diese Aufgabe die Zeit gestellt. Schon lange ist die Arbeit über das Internet eine Voraussetzung für Geschäftsanwendungen geworden. Zunächst haben wir die Möglichkeit der Internetnutzung für unseren dünnen Client hinzugefügt (einige unserer Wettbewerber haben übrigens dabei halt gemacht; andere hingegen haben auf den dünnen Client verzichtet und sich auf die Umsetzung des Webclients beschränkt). Wir haben uns hingegen entschieden, unseren Nutzern die Wahl zu lassen, welche Client-Option für sie am besten geeignet ist.

Über den 1C-Webclient

Die Implementierung der Internetnutzung für den Thin Client war ein umfassendes Projekt, das eine vollständige Neugestaltung der Client-Server-Interaktion erforderte. Die Entwicklung eines Web-Clients ist sogar ein ganz neues Projekt, das bei null begann.

Problemstellung

Die Anforderungen an das Projekt sind: Der Web-Client muss die gleichen Funktionen wie der Thin Client erfüllen, nämlich:

  1. Die Benutzeroberfläche anzeigen
  2. Den Client-Code ausführen, der in 1C geschrieben ist

Die Benutzeroberfläche in 1C wird in einem visuellen Editor beschrieben, jedoch deklarativ, ohne pixelgenaue Platzierung der Elemente; es stehen etwa dreißig Typen von Benutzeroberflächenelementen zur Verfügung – Schaltflächen, Eingabefelder (Text, Zahlen, Datum/Zeit), Listen, Tabellen, Diagramme usw.

Der Client-Code in 1C kann Serveraufrufe enthalten, mit lokalen Ressourcen (Dateien usw.) arbeiten, drucken und vieles mehr.

Sowohl der Thin Client (im Web-Betrieb) als auch der Web-Client nutzen denselben Satz von Web-Services zur Kommunikation mit dem 1C-Anwendungsserver. Die Implementierung bei den Clients ist natürlich unterschiedlich – der Thin Client ist in C++ geschrieben, der Web-Client in JavaScript.

Ein wenig Geschichte

Das Projekt zur Erstellung des Web-Clients wurde 2006 gestartet und umfasste im Durchschnitt ein Team von 5 Personen. In bestimmten Phasen des Projekts wurden Entwickler hinzugezogen, um spezifische Funktionen (wie Tabellenkalkulationen, Diagramme usw.) umzusetzen; in der Regel waren dies die gleichen Entwickler, die diese Funktionen bereits im dünnen Client realisiert hatten. Das bedeutet, dass die Entwickler die zuvor in C++ erstellten Komponenten erneut in JavaScript schrieben.

Von Anfang an haben wir die Idee einer automatischen (auch nur teilweisen) Konversion von C++-Code des dünnen Clients in den JavaScript-Web-Client aufgrund der erheblichen konzeptionellen Unterschiede zwischen diesen beiden Sprachen verworfen; der Web-Client wurde von Grund auf in JavaScript geschrieben.

In den ersten Iterationen des Projekts konvertierte der Web-Client den Client-Code in der eingebetteten Sprache 1C direkt in JavaScript. Der dünne Client funktioniert anders – der Code in der eingebetteten Sprache 1C wird in Bytecode kompiliert, der dann auf dem Client interpretiert wird. Später übernahm auch der Web-Client dieses Verfahren – erstens verbesserte es die Leistung, und zweitens ermöglichte es die Vereinheitlichung der Architektur von dünnem und Web-Client.

Die erste Version der 1C:Enterprise-Plattform mit Unterstützung für den Web-Client wurde 2009 veröffentlicht. Zu diesem Zeitpunkt unterstützte der Web-Client zwei Browser – Internet Explorer und Firefox. Ursprünglich war die Unterstützung von Opera geplant, jedoch mussten wir aufgrund unüberwindbarer Probleme mit den Anwendungsbeendigungs-Handlern in Opera (es war nicht möglich, mit 100%iger Sicherheit festzustellen, ob die Anwendung geschlossen wurde, und zu diesem Zeitpunkt das Trennen vom 1C-Anwendungsserver durchzuführen) von diesen Plänen absehen.

Projektstruktur

Insgesamt gibt es auf der 1C:Enterprise-Plattform 4 Projekte, die in JavaScript geschrieben sind:

  1. WebTools – allgemeine Bibliotheken, die von den anderen Projekten verwendet werden (dazu zählen wir auch Google Closure Library).
  2. Steuerelement FormatierterDokument (implementiert in JavaScript sowohl im Thin Client als auch im Web-Client)
  3. Steuerelement Scheduler (implementiert in JavaScript sowohl im Thin Client als auch im Web-Client)
  4. Web-Client

Die Struktur jedes Projekts ähnelt der Struktur von Java-Projekten (oder .NET-Projekten – je nach Vorliebe); wir haben Namespaces, und jeder Namespace befindet sich in einem eigenen Ordner. Innerhalb des Ordners befinden sich die Dateien und Klassen des Namespaces. Im Web-Client-Projekt gibt es etwa 1000 Dateien.

Strukturell wird der Web-Client grob in die folgenden Teilsysteme unterteilt:

  • Verwaltete Benutzeroberfläche der Client-Anwendung
    • Allgemeine Benutzeroberfläche der Anwendung (Systemmenüs, Panels)
    • Oberfläche der verwalteten Formulare, einschließlich etwa 30 Steuerelementen (Schaltflächen, verschiedene Eingabefelder – Text, Zahlen, Datum/Uhrzeit usw., Tabellen, Listen, Grafiken usw.)

  • Objektmodell, das Entwicklern auf der Client-Seite zur Verfügung steht (insgesamt über 400 Typen: Objektmodell der verwalteten Benutzeroberfläche, Einstellungen zur Datenanordnung, bedingte Formatierung usw.)
  • Interpreter der eingebetteten Sprache 1C
  • Browsererweiterungen (werden für Funktionen verwendet, die in JavaScript nicht unterstützt werden)
    • Arbeiten mit Kryptografie
    • Arbeiten mit Dateien
    • Technologie externer Komponenten, die ihre Nutzung sowohl im schlanken als auch im Web-Client ermöglicht

Entwicklungsmerkmale

Die Umsetzung all dessen in JavaScript ist eine herausfordernde Aufgabe. Möglicherweise ist der 1C-Web-Client eine der größten client-seitigen Anwendungen, die in JavaScript geschrieben wurden – etwa 450.000 Zeilen. Wir verwenden in unserem Code des Web-Clients aktiv einen objektorientierten Ansatz, der die Arbeit mit einem so großen Projekt vereinfacht.

Um die Größe des Client-Codes zu minimieren, haben wir zunächst unseren eigenen Obfuskator verwendet und ab Version 8.3.6 der Plattform (Oktober 2014) den Google Closure Compilereingesetzt. Die Auswirkungen der Verwendung in Zahlen – die Größe des Web-Client-Frameworks nach der Obfuskation:

  • Eigener Obfuskator – 1556 kB
  • Google Closure Compiler – 1073 kB

Die Verwendung des Google Closure Compilers hat uns geholfen, die Leistung des Web-Clients um 30 % im Vergleich zu unserem eigenen Obfuskator zu steigern. Darüber hinaus wurde der Speicherverbrauch der Anwendung um 15-25 % (je nach Browser) reduziert.

Der Google Closure Compiler funktioniert sehr gut mit objektorientiertem Code, weshalb seine Effizienz für den Web-Client maximal hoch ist. Der Closure Compiler bietet uns mehrere Vorteile:

  • Statische Typprüfung während des Builds des Projekts (ermöglicht durch die Abdeckung des Codes mit JSDoc-Anmerkungen). Das Ergebnis ist eine statische Typisierung, die in etwa dem Niveau der Typisierung in C++ entspricht. Dies hilft, einen beträchtlichen Anteil an Fehlern bereits während der Kompilierungsphase des Projekts zu erkennen.
  • Reduzierung der Codegröße durch Obfuskation
  • Eine Reihe von Optimierungen des ausgeführten Codes, wie beispielsweise:
    • Inline-Ersetzungen von Funktionen. Der Funktionsaufruf in JavaScript ist eine relativ teure Operation, und Inline-Ersetzungen häufig verwendeter kleiner Methoden beschleunigen die Ausführung des Codes erheblich.
    • Die Berechnung von Konstanten zur Compile-Zeit. Wenn ein Ausdruck von einer Konstanten abhängt, wird der tatsächliche Wert der Konstanten eingesetzt.

Als Entwicklungsumgebung für den Webclient verwenden wir WebStorm.

Für die Codeanalyse nutzen wir SonarQube, in das wir statische Code-Analysatoren integrieren. Mit Hilfe der Analysatoren überwachen wir die Qualität des Quellcodes in JavaScript und bemühen uns, eine Verschlechterung zu vermeiden.

Über den 1C-Webclient

Welche Aufgaben wir gelöst haben / lösen

Während der Umsetzung des Projekts sind wir auf eine Reihe interessanter Herausforderungen gestoßen, die es zu bewältigen galt.

Datenaustausch mit dem Server und zwischen Fenstern

Es gibt Situationen, in denen das Obfuskieren des Quellcodes die Funktionalität des Systems beeinträchtigen kann. Der externe Code im Vergleich zum ausführbaren Code des Webclients könnte aufgrund der Obfuskation Funktionsnamen und Parameter verwenden, die von dem abweichen, was unser ausführbarer Code erwartet. Der externe Code für uns ist:

  • Der Code, der vom Server in Form von strukturierten Daten kommt
  • Der Code eines anderen Anwendungsfensters

Um Obfuskation bei der Interaktion mit dem Server zu vermeiden, verwenden wir das 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;
}

Um Obfuskation bei der Interaktion mit anderen Fenstern zu vermeiden, nutzen wir sogenannte exportierbare Schnittstellen (Schnittstellen, bei denen alle Methoden exportierbar sind).

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

Wir haben das Virtual DOM verwendet, bevor es Mainstream wurde

Wie alle Entwickler, die mit komplexen Web-UI zu tun haben, haben wir schnell erkannt, dass das DOM nicht gut für die Arbeit mit dynamischen Benutzeroberflächen geeignet ist. Praktisch sofort wurde ein Äquivalent zum Virtual DOM implementiert, um die Arbeit mit der Benutzeroberfläche zu optimieren. Während der Ereignisverarbeitung werden alle DOM-Änderungen im Speicher festgehalten, und erst nach Abschluss aller Operationen werden die gesammelten Änderungen auf den DOM-Baum angewendet.

Optimierung der Web-Client-Performance

Um die Geschwindigkeit unseres Web-Clients zu erhöhen, nutzen wir so weit wie möglich die standardmäßigen Funktionen des Browsers (CSS usw.). Die Befehlszeile des Formulars (die sich praktisch in jedem Anwendungsformular befindet) wird ausschließlich mit Mitteln des Browsers und dynamischem Layout auf Basis von CSS gerendert.

Über den 1C-Webclient

Testen

Für funktionale Tests und Leistungstests nutzen wir ein hauseigenes Tool (entwickelt in Java und C++), sowie eine Testreihe, die auf basiert Selenium.

Unser Werkzeug ist universell einsetzbar – es ermöglicht das Testen nahezu aller Windows-Anwendungen und eignet sich somit sowohl für das Testen von Desktop- als auch von Web-Clients. Das Tool zeichnet die Aktionen des Benutzers auf, der die Anwendung „1C“ gestartet hat, in eine Skriptdatei. Gleichzeitig werden Bilder des Arbeitsbereichs des Bildschirms – Referenzen – aufgenommen. Bei der Überprüfung neuer Versionen des Web-Clients werden die Skripte ohne Benutzereingriff wiedergegeben. Bei einer Diskrepanz zwischen dem Screenshot und der Referenz zu einem bestimmten Zeitpunkt gilt der Test als fehlgeschlagen, woraufhin ein Qualitätsspezialist eine Untersuchung einleitet – ob es sich um einen Fehler oder um eine geplante Änderung des Systemverhaltens handelt. Bei einem geplanten Verhalten werden die Referenzen automatisch durch neue ersetzt.

Das Tool misst auch die Leistungskennzahlen von Anwendungen mit einer Genauigkeit von bis zu 25 Millisekunden. In einigen Fällen wiederholen wir Teile des Skripts (zum Beispiel die Bestellung mehrfach), um eine Analyse der zeitlichen Verschlechterung über die Zeit durchzuführen. Alle Messergebnisse werden im Log gespeichert, um sie zu analysieren.

Über den 1C-Webclient
Unser Testtool und die getestete Anwendung

Unser Tool und Selenium ergänzen sich; zum Beispiel, wenn sich eine Schaltfläche auf einem der Bildschirme verschoben hat – kann Selenium das möglicherweise nicht erkennen, aber unser Tool wird es bemerken, da es einen pixelgenauen Vergleich des Screenshots mit dem Referenzbild durchführt. Zudem kann das Tool Probleme bei der Eingabeverarbeitung über die Tastatur oder Maus erkennen, da es genau diese Eingaben simuliert.

Mit beiden Tools (unserem und Selenium) führen wir Tests durch, die typische Arbeitsszenarien aus unseren Anwendungen simulieren. Die Tests werden automatisch nach dem täglichen Build der Plattform „1C:Enterprise“ gestartet. Bei einer Verlangsamung der Abläufe im Vergleich zum vorherigen Build führen wir eine Untersuchung durch und beheben die Ursachen der Verlangsamung. Unser Kriterium ist einfach – der neue Build muss nicht langsamer als der vorherige arbeiten.

Für die Untersuchung von Verlangsamungsereignissen nutzen die Entwickler verschiedene Tools; vor allem wird Dynatrace AJAX Edition des Unternehmens DynaTrace. Es erfolgt eine Protokollierung der Ausführung von problematischen Operationen in der vorherigen und der neuen Version, gefolgt von einer Analyse der Logs. Dabei kann die Ausführungszeit einzelner Operationen (in Millisekunden) nicht der entscheidende Faktor sein – im Browser werden sporadisch Hintergrundprozesse wie die Müllbereinigung gestartet, die die Ausführungszeit von Funktionen beeinflussen und das Bild verzerren können. Relevantere Parameter sind in diesem Fall die Anzahl der ausgeführten JavaScript-Anweisungen, die Anzahl der atomaren Operationen am DOM usw. Wenn die Anzahl der Anweisungen/Operationen im gleichen Szenario in der neuen Version gestiegen ist, bedeutet dies fast immer einen Leistungsabfall, den es zu beheben gilt.

Ein weiterer Grund für die Leistungsprobleme könnte sein, dass der Google Closure Compiler aus verschiedenen Gründen die Inline-Ersatzfunktion nicht durchführen konnte (zum Beispiel, weil die Funktion rekursiv oder virtuell ist). In diesem Fall versuchen wir, die Situation zu verbessern, indem wir den Quellcode umschreiben.

Browsererweiterungen

Wenn eine Anwendung Funktionalitäten benötigt, die JavaScript nicht bietet, verwenden wir Browsererweiterungen:

Unsere Erweiterungen bestehen aus zwei Teilen. Der erste Teil ist das, was man als Browsererweiterung bezeichnet (in der Regel in JavaScript geschriebene Erweiterungen für Chrome und Firefox), die mit dem zweiten Teil – einer binären Erweiterung, die die benötigte Funktionalität implementiert – interagieren. Es ist erwähnenswert, dass wir drei Versionen der binären Erweiterungen schreiben – für Windows, Linux und MacOS. Die binäre Erweiterung wird als Teil der Plattform 1C:Enterprise bereitgestellt und befindet sich auf dem Server der 1C-Anwendung. Bei der ersten Anforderung vom Web-Client wird sie auf den Client-Computer geladen und im Browser installiert.

Bei der Arbeit in Safari verwenden unsere Erweiterungen NPAPI, während sie in Internet Explorer die ActiveX-Technologie nutzen. Microsoft Edge unterstützt derzeit keine Erweiterungen, weshalb der Web-Client dort mit Einschränkungen funktioniert.

Weitere Entwicklungen

Eine der Aufgabenstellungen für das Team, das für den Web-Client zuständig ist, besteht darin, die Funktionalität weiterzuentwickeln. Die Funktionalität des Web-Clients sollte identisch mit der des Thin Clients sein, wobei alle neuen Funktionen gleichzeitig in beiden Clients implementiert werden.

Weitere Aufgaben umfassen die Weiterentwicklung der Architektur, Refactoring sowie die Verbesserung der Leistung und Zuverlässigkeit. Ein Schwerpunkt liegt beispielsweise auf der schrittweisen Umsetzung eines asynchronen Betriebsmodells. Derzeit basiert ein Teil der Funktionalität des Web-Clients auf einem synchronen Modell der Kommunikation mit dem Server. Asynchrone Modelle gewinnen nicht nur in Browsern zunehmend an Bedeutung, sodass wir gezwungen sind, den Web-Client anzupassen, indem wir synchrone Aufrufe durch asynchrone ersetzen (samt dem entsprechenden Refactoring des Codes). Der schrittweise Übergang zu einem asynchronen Modell ist notwendig, um die veröffentlichten Lösungen zu unterstützen und diese schrittweise anzupassen.

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster