Jak działa przeglądarka

Cykl życia żądania dokumentu

Doconut renderuje dokumenty jako obrazy podzielone na strony, serwowane przez obsługę HTTP, którą rejestruje twój Web.config. Zrozumienie cyklu życia — otwarcie, token, żądania stron, zamknięcie — wyjaśnia prawie każde zachowanie, które zaobserwujesz, w tym komunikaty o błędach.

Ruchome części

  • Viewer — publiczna usługa, którą rozwiążesz z DoconutHost.Services. Otwiera dokumenty i zwraca tokeny sesji.
  • Sesja dokumentu — obiekt po stronie serwera przechowujący załadowany dokument, utrzymywany w pamięci pod swoim tokenem.
  • DocImage.axd — Doconut.DocImageHandler zadeklarowany w Web.config. Odpowiada na każde żądanie, które wysyła widget przeglądarki (strony, miniatury, wyszukiwanie, adnotacje, …), zawsze identyfikowany tokenem.
  • /doconut-res/* — Doconut.DoconutResourceModule, który dostarcza własne skrypty, style i ikony widgetu.

Viewer jest bezstanowy — z założenia

Viewer nie przechowuje stanu dokumentu per żądanie i nie implementuje IDisposable. Sesje istnieją niezależnie od niego i są czyszczone po wygaśnięciu lub po wyraźnym CloseDocument(token). System.Web nie posiada wstrzykiwania przez konstruktor, więc rozwiąż go tam, gdzie jest potrzebny — typowo w akcji kontrolera:

csharp
// POST /ViewerApi/Open?fileName=Sample.pdf
[HttpPost]
public async Task<ActionResult> Open(string fileName)
{
    var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
    var path   = Server.MapPath("~/files/" + Path.GetFileName(fileName));

    var token = await viewer.OpenDocumentAsync(path);
    return Content(token, "text/plain");
}

Co się dzieje wewnątrz OpenDocumentAsync

  1. Bramka licencyjna. Odrzucona licencja (sfabrykowana, na czarnej liście lub kompilacja poza oknem aktualizacji licencji) natychmiast rzuca LicenseException, podając przyczynę jako komunikat. Otwieranie nigdy nie degraduje się cicho przy nieprawidłowej licencji; brakująca licencja jedynie dodaje znak wodny.
  2. Tworzenie sesji. Fabryka przeglądarki wybiera przeglądarkę formatu dla rozszerzenia pliku i ładuje dokument (zobacz Cykl renderowania). Sesja jest przechowywana w pamięci pod nowym losowym tokenem z przesuwanym wygaśnięciem wynoszącym DocOptions.TimeOut minut (domyślnie 60). Każde żądanie strony resetuje licznik.
  3. Przyznanie dostępu. Przy użyciu UnsafeMode = false (domyślnie), token jest powiązany z sesją ASP.NET żądania, które go otworzyło: wpis secure-{token} jest zapisywany w tej sesji. Otwarcie musi więc odbywać się w żądaniu ze stanem sesji — zobacz Sesje i bezpieczeństwo.
  4. Token jest zwracany. To jedyny identyfikator, którego przeglądarka potrzebuje do wszystkiego, co następuje.

Asynchroniczne przeciążenia przyjmują ścieżkę do pliku, ścieżkę do pliku plus konfigurację per-format (PdfConfig, WordConfig, …), lub Stream plus FileInfo, którego rozszerzenie wybiera format. Dla kodu zaplecza Web Forms, który nie używa asynchronicznych stron, OpenDocument oferuje te same trzy wejścia synchronicznie (ścieżka, strumień z nazwą pliku lub tablica bajtów z nazwą pliku).

Jak widget pobiera strony

Widget wywołuje DocImage.axd z tokenem w ciągu zapytania. To, co robi obsługa, zależy od żądania:

ZapytanieCel
?token=…&page=NWygenerowany obraz strony (PNG)
?token=…&page=N&thumb=1Miniatura
?token=…&zoom=…Renderowanie powiększonej strony
?token=…&search=termWyszukiwanie pełnotekstowe (ograniczone licencją)
?token=…&bookmarksZarys dokumentu i zakładki
?token=…&copy / &showlinks / &fileFormat / &metaKopiowanie tekstu, hiperłącza, informacje o formacie, metadane DICOM
?token=…&action=rotate/flip/closeAkcje strony i wyraźne zamknięcie (POST)
?token=…&AnnSave=… / &AnnLoadZapis i wczytywanie adnotacji

Każde żądanie jest najpierw sprawdzane:

  • Brak tokenu → 404, lub baner wersji gdy ShowDoconutInfo = true.
  • Token nie przyznany tej sesji ASP.NET → obraz błędu z napisem You Are Not Authorized To View This Page.
  • Nieznany lub wygasły token → obraz błędu z napisem Document session not found. Please re-open document.

Obrazy błędów to zwykłe pliki PNG wysyłane ze statusem 200, więc widget może je wyświetlić tam, gdzie znajdowałaby się strona. Kontrola monitorująca, która sprawdza tylko kod statusu, zgłosi je jako dostarczone strony; prawdziwa strona ma dziesiątki do setek kilobajtów, obraz błędu około 2 KB.

Zamykanie dokumentu

csharp
viewer.CloseDocument(token);

CloseDocument usuwa sesję (zwalniając natychmiast silnik dokumentu i jego pamięć), usuwa wpis secure-{token} z bieżącej sesji ASP.NET żądania i unieważnia token. Jest to opcjonalne — przesuwane wygaśnięcie wykonuje tę samą czyszczenie — ale dla dużych dokumentów zwalnia pamięć w momencie, gdy użytkownik skończy. Z przeglądarki, objViewer.Close(true) wysyła równoważne żądanie zamknięcia do DocImage.axd.

Najważniejsze wnioski

  • Jeden otwarty dokument = jedna sesja = jeden token, przyznany sesji ASP.NET, która go otworzyła.
  • Token wygasa w przesuwanym oknie; przeglądarka pozostawiona bezczynna po DocOptions.TimeOut wymaga ponownego otwarcia.
  • Viewer może być rozwiązany i udostępniany dowolnie; sesje przenoszą cały stan.

Czy ta strona była pomocna?