Jak działa Viewer
Cykl życia żądania dokumentu
Doconut renderuje dokumenty jako obrazy podzielone na strony, serwowane przez middleware ASP.NET Core. Zrozumienie cyklu życia — otwarcie, token, żądania stron, zamknięcie — wyjaśnia prawie każde zachowanie, które zaobserwujesz, włącznie z komunikatami o błędach.
Trzy elementy składowe
Viewer— publiczna usługa, którą wstrzykujesz. Otwiera dokumenty i zwraca tokeny sesji.- Sesja dokumentu — obiekt po stronie serwera przechowujący załadowany dokument, indeksowany tokenem w
IMemoryCache. - Middleware Doconut — dodany przez
UseDoconut(); odpowiada na każde żądanie wysyłane przez widget przeglądarki (pages,thumbnails,search,annotations, …), zawsze uwierzytelnione tokenem.
Viewer jest bezstanowy — z założenia
Viewer jest zamknięty (sealed), nie przechowuje żadnego stanu dokumentu per żądanie i celowo nie implementuje IDisposable. Sesje istnieją niezależnie w menedżerze sesji i są czyszczone przez wygaśnięcie pamięci podręcznej lub wywołanie CloseDocument(token).
Nie tworzysz go już ręcznie. AddDoconut() rejestruje go jako usługę przejściową; wstrzykuj go tam, gdzie jest potrzebny:
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
var token = await viewer.OpenDocumentAsync($"files/{fileName}");
return Results.Content(token, "text/plain");
});W aplikacji MVC przyjmij go jako parametr konstruktora; w widoku Razor użyj @inject Doconut.Viewer Viewer. Pamięci podręczne aplikacji przechowujące instancje Viewer nie są już potrzebne — i nie są już poprawne, ponieważ nie przechowują niczego wartego buforowania.
Co się dzieje wewnątrz OpenDocumentAsync
- Bramka licencyjna. Odrzucona lub przeterminowana licencja (czarna lista, zmodyfikowana lub kompilacja poza oknem aktualizacji licencji) natychmiast rzuca
LicenseExceptionz powodem odrzucenia jako komunikatem — otwieranie nigdy nie degraduje cicho przy nieprawidłowej (w przeciwieństwie do nieobecnej) licencji. Licencja tymczasowa lub subskrypcyjna, której termin kalendarzowy wygasł, jest wyjątkiem: nie rzuca wyjątku — degraduje do znaku wodnego. - Tworzenie sesji. Fabryka viewerów wybiera odpowiedni viewer formatu dla rozszerzenia pliku i ładuje dokument (zobacz Rendering Pipeline). Sesja jest przechowywana w
IMemoryCachepod nowym tokenem GUID z przesuwanym wygaśnięciem —DocOptions.TimeOutminut, domyślnie 60. Każde żądanie strony resetuje licznik. - Rejestracja zabezpieczeń. Przy
UnsafeMode = false(wartość domyślna), token jest powiązany z sesją ASP.NET wywołującego: w sesji zapisywany jest znaczniksecure-{token}, więc tylko sesja przeglądarki, która otworzyła dokument, może żądać jego stron. - Token jest zwracany. Jest jedynym poświadczeniem dla wszystkiego, co następuje.
Nie ma osobnego kroku rozgrzewki. Poprzednia biblioteka udostępniała InitCache() w tym celu; już nie istnieje i nic go nie zastępuje.
Trzy przeciążenia różnią się jedynie wejściem: ścieżka do pliku, ścieżka do pliku plus konfiguracja per format (PdfConfig, WordConfig, …) lub Stream plus FileInfo, którego rozszerzenie określa format.
Jak widget pobiera strony
Widget kliencki wywołuje middleware Doconut z tokenem w ciągu zapytania. To, co robi middleware, zależy od żądania:
| Zapytanie | Cel |
|---|---|
?token=…&page=N | Wygenerowany obraz strony (PNG) |
?token=…&page=N&thumb=1 | Miniatura |
?token=…&zoom=… | Renderowanie powiększonej strony |
?token=…&search=term | Wyszukiwanie pełnotekstowe (z bramką licencyjną) |
?token=…&bookmarks | Spis treści/dodruki dokumentu |
?token=…© / &showlinks / &fileFormat | Kopiowanie tekstu, hiperłącza i informacje o formacie |
?token=…&meta | Metadane techniczne DICOM; zwraca 501 dla sesji DICOM w tym pakiecie |
?token=…&action=rotate/flip/close | Akcje na stronie i wyraźne zamknięcie |
?token=…&AnnSave=… / &AnnLoad | Zapis/odczyt adnotacji |
Każda z tych ścieżek najpierw podlega walidacji:
- Brak tokenu → middleware zwraca 404 (lub baner wersji, gdy
ShowDoconutInfo = true). - Nieznany lub wygasły token → obraz błędu z komunikatem
Document session not found. Please re-open document. - Brak middleware sesji (przy
UnsafeMode = false) → HTTP 500 z komunikatemSession middleware not configured. Call UseSession() before UseDoconut(). - Token otwarty w innej sesji przeglądarki → obraz błędu z komunikatem
You Are Not Authorized To View This Page.
Gdzie montowany jest middleware
UseDoconut() odpowiada na żądania zawierające token, niezależnie od miejsca montażu. Aplikacja referencyjna zachowuje historyczną strukturę żądania DocImage.axd na gałęzi MapWhen, więc istniejący klient nadal wywołuje ten sam URL. Niezależnie od wyboru, BasePath klienta musi się z nim zgadzać — zobacz ViewerConfig.
Serwowanie stron z współdzielonego magazynu zamiast z węzła otwierającego to zupełnie inny układ; zobacz Rozproszone wdrożenia.
Zamykanie dokumentu
viewer.CloseDocument(token);CloseDocument usuwa sesję z pamięci podręcznej (co zwalnia podlegający silnik dokumentu i natychmiast zwalnia jego pamięć), usuwa znacznik secure-{token} i cofa przyznany dostęp. Wywołanie jest opcjonalne — przesuwane wygaśnięcie wykonuje tę samą automatyczną czyszczenie — ale dla dużych dokumentów jest to uprzejmy sposób zwolnienia pamięci w momencie, gdy użytkownik skończył.
Jest wywoływane na wstrzykniętym Viewer. Poprzedni wzorzec — tworzenie krótkotrwałego Viewer w bloku using wyłącznie po to, by zamknąć token — nie ma odpowiednika i nie jest potrzebny.
Najważniejsze wnioski
- Jeden otwarty dokument = jedna sesja = jeden token. Tokeny są powiązane z sesją przeglądarki, nie są globalnymi URL‑ami.
- Token wygasa w przesuwanym oknie; viewer pozostawiony bezczynny dłużej niż
DocOptions.TimeOutwymaga ponownego otwarcia. Viewermoże być wstrzykiwany i współdzielony dowolnie; sesje przenoszą cały stan.
Czy ta strona była pomocna?