1C web istemcisi hakkında

1C:Enterprise teknolojisinin güzel özelliklerinden biri, yönetilen form teknolojisi kullanılarak geliştirilen uygulama çözümünün hem Windows, Linux, MacOS X için ince (yürütülebilir) bir istemcide hem de 5 tarayıcı için bir web istemcisi olarak başlatılabilmesidir - Uygulamanın kaynak kodunu değiştirmeden Chrome, Internet Explorer, Firefox, Safari, Edge ve bunların tümü. Üstelik harici olarak ince istemcideki ve tarayıcıdaki uygulama işlevleri ve neredeyse aynı görünüyor.
10 fark bulun (kesimin altında 2 resim):

Linux'ta ince istemci penceresi:

1C web istemcisi hakkında

Web istemcisindeki aynı pencere (Chrome tarayıcısında):

1C web istemcisi hakkında

Neden bir web istemcisi yaptık? Biraz acıklı bir şekilde ifade etmek gerekirse, zaman bize böyle bir görev yükledi. İnternet üzerinden çalışmak uzun zamandır iş uygulamaları için bir ön koşul olmuştur. İlk olarak, ince istemcimiz için İnternet üzerinden çalışma yeteneğini ekledik (bu arada rakiplerimizden bazıları orada durdu; diğerleri ise tam tersine ince istemciyi terk etti ve kendilerini bir web istemcisi uygulamakla sınırladı). Kullanıcılarımıza kendilerine en uygun müşteri seçeneğini seçme fırsatını vermeye karar verdik.

1C web istemcisi hakkında

İnce istemciye web tabanlı yetenekler eklemek, istemci-sunucu mimarisinde tam bir değişiklik içeren büyük bir projeydi. Bir web istemcisi oluşturmak, sıfırdan başlayan tamamen yeni bir projedir.

Sorunun formüle edilmesi

Yani proje gereksinimleri: web istemcisi, ince istemciyle aynı şeyi yapmalıdır:

  1. Kullanıcı arayüzünü görüntüle
  2. 1C dilinde yazılmış müşteri kodunu yürütün

1C'deki kullanıcı arayüzü, görsel bir düzenleyicide, ancak bildirimsel olarak, öğelerin piksel piksel düzenlenmesi olmadan tanımlanır; Yaklaşık üç düzine türde arayüz öğesi kullanılır: düğmeler, giriş alanları (metin, sayısal, tarih/saat), listeler, tablolar, grafikler vb.

1C dilindeki istemci kodu, sunucu çağrılarını, yerel kaynaklarla (dosyalar vb.) Çalışmayı, yazdırmayı ve çok daha fazlasını içerebilir.

Hem ince istemci (web üzerinden çalışırken) hem de web istemcisi, 1C uygulama sunucusuyla iletişim kurmak için aynı web hizmetleri kümesini kullanır. İstemci uygulamaları elbette farklıdır; ince istemci C++ ile yazılmıştır, web istemcisi ise JavaScript ile yazılmıştır.

Biraz tarih

Web client projesi 2006 yılında ortalama 5 kişilik bir ekiple başladı. Projenin belirli aşamalarında, geliştiriciler belirli işlevlerin (elektronik tablo belgesi, diyagramlar vb.) uygulanmasına dahil edildi; kural olarak bunlar, ince istemcide bu işlevi gerçekleştiren geliştiricilerle aynıydı. Onlar. geliştiriciler daha önce C++'da oluşturdukları bileşenleri JavaScript'te yeniden yazdılar.

En başından beri, iki dil arasındaki güçlü kavramsal farklılıklar nedeniyle, C++ ince istemci kodunun JavaScript web istemcisine herhangi bir otomatik (hatta kısmen) dönüştürülmesi fikrini reddettik; web istemcisi sıfırdan JavaScript ile yazılmıştır.

Projenin ilk yinelemelerinde web istemcisi, yerleşik 1C dilindeki istemci kodunu doğrudan JavaScript'e dönüştürdü. İnce istemci farklı davranır - yerleşik 1C dilindeki kod bayt koduna derlenir ve ardından bu bayt kodu istemcide yorumlanır. Daha sonra web istemcisi de aynısını yapmaya başladı - ilk olarak performans artışı sağladı ve ikinci olarak ince ve web istemcilerinin mimarisini birleştirmeyi mümkün kıldı.

1C:Enterprise platformunun web istemci desteğine sahip ilk sürümü 2009 yılında piyasaya sürüldü. O zamanki web istemcisi 2 tarayıcıyı destekliyordu - Internet Explorer ve Firefox. Orijinal planlar Opera desteğini içeriyordu ancak o dönemde Opera'daki uygulama kapatma işleyicileriyle ilgili aşılmaz sorunlar nedeniyle (uygulamanın kapandığını %100 kesin olarak takip etmek mümkün değildi ve o anda bağlantı kesme prosedürünü gerçekleştirmek mümkün değildi) 1C uygulama sunucusu) bu planlardan vazgeçilmesi gerekiyordu.

Proje yapısı

Toplamda 1C:Enterprise platformunun JavaScript ile yazılmış 4 projesi vardır:

  1. WebTools – diğer projeler tarafından kullanılan paylaşılan kütüphaneler (ayrıca şunları da dahil ediyoruz) Google Kapatma Kitaplığı).
  2. Kontrol elemanı BiçimlendirilmişBelge (hem ince istemcide hem de web istemcisinde JavaScript'te uygulanır)
  3. Kontrol elemanı zamanlayıcı (hem ince istemcide hem de web istemcisinde JavaScript'te uygulanır)
  4. Web istemcisi

Her projenin yapısı Java projelerinin (veya .NET projelerinin (hangisi daha yakınsa)) yapısına benzer; Ad alanlarımız var ve her ad alanı ayrı bir klasördedir. Klasörün içinde dosyalar ve ad alanı sınıfları vardır. Web istemcisi projesinde yaklaşık 1000 dosya bulunmaktadır.

Yapısal olarak web istemcisi büyük ölçüde aşağıdaki alt sistemlere bölünmüştür:

  • Yönetilen istemci uygulama arayüzü
    • Genel uygulama arayüzü (sistem menüleri, paneller)
    • Diğer şeylerin yanı sıra yaklaşık 30 kontrol (düğmeler, çeşitli giriş alanı türleri - metin, sayısal, tarih/saat vb., tablolar, listeler, grafikler vb.) dahil olmak üzere yönetilen formların arayüzü.

  • İstemcide geliştiricilerin kullanımına sunulan nesne modeli (toplamda 400'den fazla tür: yönetilen arayüz nesne modeli, veri düzeni ayarları, koşullu stillendirme vb.)
  • Yerleşik 1C dilinin tercümanı
  • Tarayıcı uzantıları (JavaScript'te desteklenmeyen işlevler için kullanılır)
    • Kriptografiyle çalışmak
    • Dosyalarla çalışma
    • Harici bileşenlerin teknolojisi, bunların hem ince istemcilerde hem de web istemcilerinde kullanılmasına olanak tanır

Tasarım özellikleri

Yukarıdakilerin tümünü JavaScript'te uygulamak kolay değildir. Belki de 1C web istemcisi, yaklaşık 450.000 satırla JavaScript'te yazılmış en büyük istemci tarafı uygulamalardan biridir. Web istemci kodunda, bu kadar büyük bir projeyle çalışmayı kolaylaştıran nesne yönelimli bir yaklaşımı aktif olarak kullanıyoruz.

İstemci kodunun boyutunu en aza indirmek için öncelikle kendi obfuscator'ımızı kullandık ve platform sürümü 8.3.6'dan (Ekim 2014) başlayarak kullanmaya başladık. Google Kapatma Derleyicisi. Rakamlarla kullanımın etkisi – gizleme sonrasında web istemci çerçevesinin boyutu:

  • Kendi karartıcı – 1556 kb
  • Google Kapatma Derleyicisi – 1073 kb

Google Closure Compiler'ı kullanmak, web istemcisinin performansını kendi gizleme aracımıza kıyasla %30 oranında artırmamıza yardımcı oldu. Ayrıca uygulamanın tükettiği bellek miktarı da %15-25 oranında azaldı (tarayıcıya bağlı olarak).

Google Closure Compiler, nesne yönelimli kodla çok iyi çalışır, dolayısıyla web istemcisi için verimliliği mümkün olduğu kadar yüksektir. Kapanış Derleyicisi bizim için birkaç iyi şey yapar:

  • Proje oluşturma aşamasında statik tür kontrolü (kodu JSDoc ek açıklamalarıyla kapsamamızı sağlar). Sonuç, C++'ta yazmaya çok yakın düzeyde statik yazmadır. Bu, proje derleme aşamasında oldukça büyük bir hata yüzdesinin yakalanmasına yardımcı olur.
  • Gizleme yoluyla kod boyutunu küçültme
  • Yürütülen kodun bir dizi optimizasyonu, örneğin:
    • satır içi işlev değişiklikleri. JavaScript'te bir işlevi çağırmak oldukça pahalı bir işlemdir ve sık kullanılan küçük yöntemlerin satır içi değiştirilmesi, kodu önemli ölçüde hızlandırır.
    • Derleme zamanında sabitleri saymak. Bir ifade bir sabite bağlıysa, sabitin gerçek değeri onun yerine konulacaktır.

WebStorm'u web istemcisi geliştirme ortamımız olarak kullanıyoruz.

Kod analizi için kullanıyoruz SonarQubeStatik kod analizörlerini entegre ettiğimiz yer. Analizörler kullanarak JavaScript kaynak kodunun kalitesindeki bozulmayı izliyor ve engellemeye çalışıyoruz.

1C web istemcisi hakkında

Hangi sorunları çözdük/çözüyoruz?

Projenin uygulanması sırasında çözmemiz gereken bir dizi ilginç sorunla karşılaştık.

Sunucuyla ve pencereler arasında veri alışverişi

Kaynak kodunun gizlenmesinin sistemin çalışmasına müdahale edebileceği durumlar vardır. Web istemcisinin yürütülebilir kodunun dışındaki kod, gizleme nedeniyle, yürütülebilir kodumuzun beklediğinden farklı işlev ve parametre adlarına sahip olabilir. Bizim için harici kod:

  • Veri yapıları biçiminde sunucudan gelen kod
  • Başka bir uygulama penceresinin kodu

Sunucuyla etkileşimde bulunurken karışıklığı önlemek için @expose etiketini kullanıyoruz:

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

Ve diğer pencerelerle etkileşimde bulunurken karışıklığı önlemek için, dışa aktarılan arayüzler (tüm yöntemlerin dışa aktarıldığı arayüzler) kullanıyoruz.

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

Yaygın hale gelmeden önce Virtual DOM'u kullanıyorduk)

Karmaşık Web kullanıcı arayüzleriyle uğraşan tüm geliştiriciler gibi biz de DOM'un dinamik kullanıcı arayüzleriyle çalışmaya pek uygun olmadığını hemen fark ettik. Kullanıcı arayüzüyle çalışmayı optimize etmek için neredeyse anında bir Sanal DOM analoğu uygulandı. Olay işleme sırasında tüm DOM değişiklikleri bellekte saklanır ve yalnızca tüm işlemler tamamlandığında biriken değişiklikler DOM ağacına uygulanır.

Web istemcisini optimize etme

Web istemcimizin daha hızlı çalışmasını sağlamak için standart tarayıcı özelliklerini (CSS vb.) maksimumda kullanmaya çalışıyoruz. Böylece, form komut paneli (uygulamanın hemen hemen her formunda bulunur), CSS'ye dayalı dinamik düzen kullanılarak yalnızca tarayıcı araçları kullanılarak oluşturulur.

1C web istemcisi hakkında

Test

İşlevsellik ve performans testleri için, (Java ve C++ ile yazılmış) özel bir aracın yanı sıra, Java ve C++ ile yazılmış bir test paketi kullanırız. Selenyum.

Aracımız evrenseldir; hemen hemen tüm pencereli programları test etmenize olanak tanır ve bu nedenle hem ince istemciyi hem de web istemcisini test etmek için uygundur. Araç, 1C uygulama çözümünü başlatan kullanıcının eylemlerini bir komut dosyasına kaydeder. Aynı zamanda ekranın çalışma alanının yani standartların görüntüleri de kayıt altına alınır. Web istemcisinin yeni sürümlerini izlerken komut dosyaları kullanıcı katılımı olmadan oynatılır. Ekran görüntüsünün herhangi bir adımda referans ekran görüntüsüyle eşleşmemesi durumunda test başarısız sayılır ve ardından bir kalite uzmanı bunun bir hata mı yoksa sistem davranışında planlanmış bir değişiklik mi olduğunu belirlemek için bir araştırma yapar. Planlanan davranış durumunda standartlar otomatik olarak yenileriyle değiştirilir.

Araç ayrıca uygulama performansını 25 milisaniyeye kadar doğrulukla ölçer. Bazı durumlarda, yürütme süresinin zaman içindeki bozulmasını analiz etmek için betiğin bazı kısımlarını döngüye alırız (örneğin, sipariş girişinin birkaç kez tekrarlanması). Tüm ölçümlerin sonuçları analiz için bir günlüğe kaydedilir.

1C web istemcisi hakkında
Test aracımız ve test altındaki uygulamamız

Aracımız ve Selenyum birbirini tamamlıyor; örneğin, ekranlardan birindeki bir düğmenin konumu değiştiyse Selenyum bunu takip etmeyebilir ancak aracımız bunu fark edecektir çünkü ekran görüntüsünün standartla piksel piksel karşılaştırmasını yapar. Araç aynı zamanda klavye veya fareden gelen girdilerin işlenmesiyle ilgili sorunları da izleyebilir, çünkü tam olarak yeniden ürettiği şey budur.

Her iki araçta (bizim ve Selenium) yapılan testler, uygulama çözümlerimizden tipik çalışma senaryolarını çalıştırır. 1C:Enterprise platformunun günlük kurulumundan sonra testler otomatik olarak başlatılır. Komut dosyaları daha yavaşsa (önceki yapıya kıyasla), yavaşlamanın nedenini araştırır ve çözeriz. Kriterimiz basit; yeni yapının öncekinden daha yavaş çalışmaması gerekiyor.

Geliştiriciler yavaşlama olaylarını araştırmak için farklı araçlar kullanır; esas olarak kullanılan Dynatrace AJAX Sürümü şirket üretimi DynaTrace. Sorunlu işlemin önceki ve yeni yapılarda yürütülmesine ilişkin günlükler kaydedilir, ardından günlükler analiz edilir. Aynı zamanda, tekli işlemlerin yürütme süresi (milisaniye cinsinden) belirleyici bir faktör olmayabilir - çöp toplama gibi hizmet işlemleri tarayıcıda periyodik olarak başlatılır, işlevlerin yürütme süresiyle örtüşebilir ve resmi bozabilir. Bu durumda daha alakalı parametreler, yürütülen JavaScript talimatlarının sayısı, DOM'daki atomik işlemlerin sayısı vb. olacaktır. Yeni bir sürümde aynı komut dosyasındaki talimatların/işlemlerin sayısı arttıysa, bu neredeyse her zaman performansta düzeltilmesi gereken bir düşüş anlamına gelir.

Ayrıca performanstaki düşüşün nedenlerinden biri, Google Closure Compiler'ın bazı nedenlerden dolayı işlevin satır içi değişimini gerçekleştirememesi olabilir (örneğin, işlev yinelemeli veya sanal olduğundan). Bu durumda kaynak kodunu yeniden yazarak durumu düzeltmeye çalışıyoruz.

Tarayıcı uzantıları

Bir uygulama çözümü JavaScript'te bulunmayan bir işlevselliğe ihtiyaç duyduğunda tarayıcı uzantılarını kullanırız:

  • dosyalarla çalışmak
  • kriptografiyle çalışmak için
  • birlikte çalışmak harici bileşenler

Uzantılarımız iki bölümden oluşmaktadır. İlk bölüm, tarayıcı uzantısı olarak adlandırılan (genellikle Chrome ve Firefox için JavaScript'te yazılan uzantılar) ikinci bölümle etkileşime giren, ihtiyacımız olan işlevselliği uygulayan ikili bir uzantıdır. Windows, Linux ve MacOS için ikili uzantıların 3 versiyonunu yazdığımızı belirtmekte fayda var. İkili uzantı, 1C:Enterprise platformunun bir parçası olarak sağlanır ve 1C uygulama sunucusunda bulunur. Bir web istemcisinden ilk çağrıldığında istemci bilgisayara indirilir ve tarayıcıya yüklenir.

Uzantılarımız Safari'de çalışırken NPAPI'yi kullanır; Internet Explorer'da çalışırken ActiveX teknolojisini kullanır. Microsoft Kenar henüz uzantıları desteklemediğinden, içindeki web istemcisi kısıtlamalarla çalışır.

Daha da geliştirilmesi

Web istemcisi geliştirme ekibinin görevlerinden biri işlevselliğin daha da geliştirilmesidir. Web istemcisinin işlevselliği, ince istemcinin işlevselliğiyle aynı olmalıdır; tüm yeni işlevler, hem ince hem de web istemcilerinde aynı anda uygulanır.

Diğer görevler arasında mimarinin geliştirilmesi, yeniden düzenleme, performansın ve güvenilirliğin artırılması yer alır. Örneğin yönlerden biri, eşzamansız bir çalışma modeline doğru daha fazla hareket etmektir. Web istemcisinin bazı işlevleri şu anda sunucuyla senkronize bir etkileşim modeli üzerine inşa edilmiştir. Eşzamansız model artık tarayıcılarda (ve yalnızca tarayıcılarda değil) daha alakalı hale geliyor ve bu bizi, eşzamanlı çağrıları eşzamansız olanlarla değiştirerek (ve kodu buna göre yeniden düzenleyerek) web istemcisini değiştirmeye zorluyor. Eşzamansız bir modele kademeli geçiş, yayımlanan çözümlerin desteklenmesi ihtiyacı ve bunların kademeli adaptasyonu ile açıklanmaktadır.

Kaynak: habr.com

Yorum ekle