Як працює переглядач

Життєвий цикл запиту документу

Doconut рендерить документи як розбиті на сторінки зображення, що подаються через middleware ASP.NET Core. Розуміння життєвого циклу — відкриття, токен, запити сторінок, закриття — пояснює майже всю поведінку, яку ви спостерігатимете, включаючи повідомлення про помилки.

Три рухомих частини

  • Viewer — публічний сервіс, який ви інжектуєте. Він відкриває документи та повертає токени сесії.
  • Сесія документа — об’єкт на боці сервера, що зберігає завантажений документ, індексований токеном у IMemoryCache.
  • Проміжне ПЗ Doconut — додається за допомогою UseDoconut(); відповідає на кожен запит, який робить віджет браузера (pages, thumbnails, search, annotations, …), завжди автентифікований токеном.

Viewer без стану — за задумом

Viewer є sealed, не зберігає стан документа для кожного запиту і навмисно не реалізує IDisposable. Сесії живуть незалежно в менеджері сесій і очищуються вичерпанням кешу або явним викликом CloseDocument(token).

Інжектуйте його там, де потрібно:

csharp
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
    var token = await viewer.OpenDocumentAsync($"files/{fileName}");
    return Results.Content(token, "text/plain");
});

Що відбувається всередині OpenDocumentAsync

  1. Ліцензійна перевірка. Відхилена або прострочена за версією ліцензія (чорний список, підроблена або збірка поза вікном оновлення ліцензії) миттєво викидає LicenseException з причиною відхилення у повідомленні — відкриття ніколи не деградує безшумно для недійсної (на відміну від відсутньої) ліцензії. Ліцензія типу Temporary або підписки, прострочена за календарем, є винятком: вона не викидає виключення — переходить у водяний знак.
  2. Створення сесії. Фабрика переглядача вибирає відповідний переглядач формату за розширенням файлу та завантажує документ (див. Rendering Pipeline). Сесія зберігається в IMemoryCache під новим GUID токеном з ковзним терміном діїDocOptions.TimeOut хвилин, за замовчуванням 60. Кожен запит сторінки скидає таймер.
  3. Реєстрація безпеки. При UnsafeMode = false (за замовчуванням) токен прив’язується до ASP.NET сесії виклику: маркер secure-{token} записується у сесію, тому лише браузерна сесія, яка відкрила документ, може запитувати його сторінки.
  4. Токен повертається. Це єдина облікова дані для всього, що слідує.

Три перевантаження відрізняються лише вхідними даними: шлях до файлу, шлях до файлу плюс конфігурація для формату (PdfConfig, WordConfig, …) або Stream плюс FileInfo, розширення якого визначає формат.

Як віджет отримує сторінки

Віджет клієнта викликає проміжне ПЗ Doconut з токеном у рядку запиту. Те, що робить проміжне ПЗ, залежить від запиту:

ЗапитПризначення
?token=…&page=NЗображення відрендереної сторінки (PNG)
?token=…&page=N&thumb=1Мініатюра
?token=…&zoom=…Рендеринг збільшеної сторінки
?token=…&search=termПовнотекстовий пошук (з ліцензійною перевіркою)
?token=…&bookmarksСтруктура/закладки документа
?token=…&copy / &showlinks / &fileFormat / &metaКопіювання тексту, гіперпосилання, інформація про формат, технічні метадані DICOM
?token=…&action=rotate/flip/closeДії над сторінкою та явне закриття
?token=…&AnnSave=… / &AnnLoadЗбереження/завантаження анотацій

Кожен з цих шляхів спочатку проходить валідацію:

  • Відсутній токен → проміжне ПЗ повертає 404 (або банер версії, коли ShowDoconutInfo = true).
  • Невідомий або прострочений токен → зображення помилки з текстом Document session not found. Please re-open document.
  • Відсутнє проміжне ПЗ сесії (при UnsafeMode = false) → HTTP 500 з повідомленням Session middleware not configured. Call UseSession() before UseDoconut().
  • Токен відкрито іншим браузерним сеансом → зображення помилки з текстом You Are Not Authorized To View This Page.

Закриття документа

csharp
viewer.CloseDocument(token);

CloseDocument видаляє сесію з кешу (що звільняє підлеглий движок документа та одразу звільняє пам'ять), видаляє маркер secure-{token} і відкликає доступ. Викликати його необов'язково — ковзне завершення робить те ж саме автоматично — проте для великих документів це ввічливий спосіб звільнити пам'ять, як тільки користувач закінчив.

Висновки

  • Один відкритий документ = одна сесія = один токен. Токени прив'язані до браузерної сесії, а не глобальних URL.
  • Токен закінчує термін дії у ковзному вікні; переглядач, що залишився без активності понад DocOptions.TimeOut, потребує повторного відкриття.
  • Viewer можна інжектувати та вільно ділитися; сесії несуть весь стан.

Чи була ця сторінка корисною?