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

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

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

Три складові частини

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

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

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

Ви більше не створюєте його. AddDoconut() реєструє його як транзиторний сервіс; інжектуйте його там, де потрібно:

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

У MVC‑застосунку передайте його як параметр конструктора; у Razor‑виді використовуйте @inject Doconut.Viewer Viewer. Кеші, що належать застосунку, для екземплярів Viewer більше не потрібні — і більше не є правильними, бо вони не містять нічого, що варто кешувати.

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

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

Окремого кроку прогрівання немає. Попередня бібліотека надавала InitCache() для цієї мети; вона більше не існує, і нічого її не замінює.

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

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

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

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

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

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

Де розміщено middleware

UseDoconut() відповідає на запити, що містять токен, незалежно від того, де ви його розмістите. Довідковий застосунок зберігає історичну форму запиту DocImage.axd на гілці MapWhen, тому існуючий клієнт продовжує викликати URL, який завжди використовував. Яке б рішення ви не обрали, BasePath клієнта має відповідати йому — див. ViewerConfig.

Обслуговування сторінок з спільного сховища замість вузла відкриття — це зовсім інша схема; див. Distributed Deployments.

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

csharp
viewer.CloseDocument(token);

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

Викликається це на інжектованому Viewer. Попередній шаблон — створення короткоживучого Viewer у блоці using лише для закриття токену — не має еквіваленту і не потрібен.

Висновки

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

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