Do niedawna zadanie generowania raportów przez WWW z aplikacji napisanej w Lazarusie było, powiedzmy, bardzo kreatywne. Dziś mamy przyjemność ogłosić, że w fazie testów beta znajdują się komponenty klient-serwer dla Lazarusa. Za ich pomocą można stworzyć i dostosować serwer do zdalnego generowania i eksportowania raportów, podczas gdy Twój program i przeglądarka internetowa mogą pełnić rolę klienta.
Komponenty klient-serwer w VCL FastReport zostały zaimplementowane dawno temu, ale wcześniej nie zostały zaadaptowane dla Lazarusa i działały tylko w Rad Studio Delphi i C++Builder.
Artykuł będzie przydatny nie tylko dla tych, którzy nigdy wcześniej ich nie używali, ale także dla tych, którzy chcą przenieść swój serwer FR na Linuksa, ponieważ uczciwie opisuje wszystkie zalety i wady. Odkryliśmy także problem w samym Lazarusie i znaleźliśmy sposób na jego rozwiązanie.
A teraz przejdźmy do technicznej strony zagadnienia.
Komponenty klient-serwer do raportowania w Lazarusie
Komponenty klient-serwer w Lazarusie są dostępne pod dwoma systemami operacyjnymi: Windows i Linux (tylko GTK2). Są one zaimplementowane w pakiecie "fr6CS_lazarus.lpk", którego zależności określa pakiet eksportowy, dlatego też pakiet eksportowy znajdujący się w folderze "Source/ExportPack" musi być zainstalowany przed instalacją.
Po zainstalowaniu pakietu komponentów klient/serwer, pojawi się nowa zakładka "FastReport 6.0 Klient/Serwer", w której znajdziesz 4 komponenty:
1. TfrxReportServer jest komponentem serwerowym, serwerem raportów i serwerem HTTP dwa w jednym. Jego najważniejszym polem jest ConfigFileName, gdzie należy podać ścieżkę do pliku xml z ustawieniami.
Możesz określić wiele ustawień w tym pliku, to są tylko najważniejsze z nich:
- Ustawienia samego serwera, takie jak port i czas oczekiwania;
- Ustawienia dla silnika FR, takie jak wyłączenie wykonywania skryptów;
- Orgomne możliwości ustawienia eksportu;
- Ustawienia pamięci podręcznej, takie jak czas życia pliku pamięci podręcznej, miejsce przechowywania pamięci podręcznej lub można ją całkowicie wyłączyć;
- Rejestrowanie ustawień systemowych;
- Ustawienia połączenia z bazą danych.
Więcej o wszystkich ustawieniach można przeczytać tutaj.
2. TfrxServerConnection jest komponentem klienckim, który zawiera informacje dotyczące zdalnego połączenia z TfrxReportServer, takie jak: host, port, liczba prób błędów, timeout i tak dalej.
3. TfrxReportClient, komponent kliencki, analogiczny do TfrxReport, wykonuje żądanie raportu na serwerze i wyświetla go na kliencie. Wykorzystuje komponent TfrxServerConnection do uzyskania informacji o serwerze. Może odebrać zbudowany raport z serwera i wyświetlić lub wyeksportować go wewnątrz firmy (na komputerze klienta).
4. TfrxHTTPClient jest komponentem klienckim przeznaczonym do odbierania dowolnych plików poprzez protokół HTTP. Na przykład, może żądać raportów już wyeksportowanych z serwera.
Udostępniamy również 3 aplikacje demonstracyjne:
1 server - od razu wraz z raportami i bazami danych;
2 clients - prosty i "zaawansowany".
Jako klient "Zaawansowany" możesz przeprowadzić wielowątkowe testy obciążeniowe naciskając przycisk Start:
Przypominamy również, że klientem może być zwykła przeglądarka, a generowanie strony dla klienta webowego można również skonfigurować według własnych upodobań, natomiast serwer demo jest już skonfigurowany dla klienta webowego.
"Bottle neck" GTK2
Lazarus jest wieloplatformowym IDE o otwartym kodzie źródłowym. Ale ta "beczka miodu" niestety ma w sobie również "łyżkę dziegciu". Zaczniemy od najbardziej nieprzyjemnego, czyli od serwera linuksowego.
GTK2 ma jedną bardzo nieprzyjemną cechę: możliwość pracy jednowątkowej.
Oznacza to, że nawet, jeśli 2 programy będą rysować figury na swojej BitMapie w niekończącym się cyklu, GTK2 zawęzi wszystko do 1 strumienia. Dlatego w sumie te 2 programy narysują mniej figur niż narysowałby jeden program, ponieważ część czasu zostanie poświęcona na synchronizację.
Jednak w tym przypadku synchronizacja jest organizowana bez naszego udziału.
Weźmy teraz na przykład sytuację, gdy figury są rysowane przez 1 program w kilku strumieniach (każdy strumień ma swoją lokalną BitMapę). W takim przypadku trzeba będzie stworzyć w kodzie system blokowania, bo pamiętamy o pojedynczych wątkach tej biblioteki. Ale to nie powinny być zwykłe sekcje krytyczne, tylko globalne sekcje krytyczne na poziomie GTK2. I gdy jeden z wątków wejdzie w taką krytyczną funkcję, to nawet podstawowa forma zawiesza się, aż z niej wyjdzie.
Wielowątkowość z obrazkami może być zorganizowana tylko poprzez znalezienie podobnego komponentu rysującego, który jest niezależny od GTK2 (na przykład dla tego przykładu z obrazkami), w naszym przypadku inny komponent nie jest odpowiedni.
Dlatego niektóre operacje na serwerze są zawężone do 1 strumienia.
I właśnie z powodu tej cechy lepiej nie używać dialogów, ponieważ tak długo, jak 1 klient odpowiada na dialog, budowanie raportów dla innych klientów zostanie wstrzymane.
Może pojawić się pytanie: "Dlaczego w ogóle potrzebujesz serwera jednowątkowego?" i będziesz miał częściowo rację, ponieważ jest to podobne do problemu "wąskie gardło " na drogach, gdzie całkowita przepustowość drogi jest równa przepustowości drogi w najwęższym miejscu.
Ale będziesz miał rację tylko częściowo. Tylko 3 duże operacje są zawężone do jednego przepływu: wgrywanie raportów, budowanie i eksport. Odbiór i transfer odbywają się równolegle, a dzięki systemowi cache'owania zbudowanych raportów w niektórych przypadkach nie trzeba będzie budować ich ponownie.
A to, w połączeniu z potężnym serwerem, sprawi, że problem ten będzie znacznie mniej widoczny. Jest to również problem tylko dla Linuksa (GTK2), ponieważ ten problem nie istnieje w Windows, a wraz z wydaniem GTK3 (który już obsługuje wielowątkowość) w Lazarusie zniknie on całkowicie.
Pozostałe problemy są wielokrotnie mniejsze, a nawet całkiem niezauważalne w porównaniu z tym jednym.
Co pozostało?
Niewielka część funkcjonalności została wycięta podczas przenoszenia, mianowicie CGI i system autoryzacji. Jak szybko je wdrożymy zależy od realnych zapytań o nie od naszych klientów.
Eksportowanie do HTML dla Lazarusa jest wciąż dalekie od doskonałości, klient sieciowy może i powinien być używany, ponieważ jest wygodny, ale raporty nie będą wyświetlane idealnie.
Można jednak skonfigurować system w taki sposób, aby klient sieciowy otrzymywał raporty wyeksportowane nie w HTML, lecz np. w PDF. Większość nowoczesnych przeglądarek potrafi przecież doskonale wyświetlać pliki PDF. Ten format eksportu został przez nas bardzo dobrze zaimplementowany, o czym mogą się Państwo przekonać.
Poprawka błędu w kolejce wiadomości Lazarusa 2.0.10
Również dla tych, którzy chcą używać naszych nowych komponentów w Linuksie, warto wspomnieć o jednej ważnej rzeczy: napotkaliśmy błąd w blokowaniu kolejki wiadomości i nie mogliśmy go obejść. Udało nam się skontaktować z programistami Lazarusa, naprawili oni już ten problem i w następnej wersji Lazarusa wszystko będzie działać poprawnie. Na razie, w wersji 2.0.10 i późniejszych, ten błąd będzie musiał być naprawiony lokalnie. Nie zajmie to wiele wysiłku ani czasu, wszystkom, co musisz zrobić to dodać 3 linie do jednego z plików Lazarusa i przebudować go:
1. Otwórz folder, w którym znajduje się Lazarus (na Ubuntu, na przykład "/usr/share/lazarus/2.0.10")
2. Otwórz w nim plik ~/lcl/interfaces/gtk2/gtk2msgqueue.pp.
3. Znajdź procedurę: procedure TGtkMessageQueue.Lock;
4. W tej procedurze znajdź linię: g_main_context_acquire(FMainContext);
Kod ten nie bierze pod uwagę faktu, że funkcja g_main_context_acquire może zawieść.
Więc zastąp to:
repeat until g_main_context_acquire(FMainContext);
To znaczy, że wywołujemy g_main_context_acquire w cyklu, aż zwróci True (zakończone sukcesem).
Zapraszamy do wypróbowania naszych nowych komponentów dla Lazarusa, ale przypominamy, że jest to wersja beta i będzie ona udoskonalana w zależności od potrzeb. W razie jakichkolwiek błędów prosimy o kontakt z zespołem supportu.