
Переглядач без стану — Як створити мінімальну .NET 8 відкриту кінцеву точку
Переглядач без стану — за задумом
Viewer не зберігає жодних даних документа на запит. Це закритий клас, він ніколи не реалізує IDisposable, і кожен документ, який ви відкриваєте, живе в окремій сесії, яку керує кеш фреймворка. Через це ви можете інжектити один екземпляр Viewer у будь‑якому місці вашого додатку ASP.NET Core і безпечно викликати його з багатьох одночасних запитів.
Наслідки безстанового сервісу
- Немає прихованих ресурсів – сервіс сам ніколи не виділяє великі буфери, які потребують явного очищення.
- Потокобезпечно за замовчуванням – оскільки не зберігається стан, специфічний для запиту, той самий екземпляр
Viewerможе використовуватись кількома потоками без блокувань. - Масштабовані розгортання – горизонтальне масштабування працює «з коробки»; вам не потрібні прилиплі сесії або прив’язка до сервера, лише токен сесії, який тримає клієнт.
Уся інформація, специфічна для документа (сторінки, анотації, індекс пошуку), зберігається у сесії, створеній OpenDocumentAsync. Сесія зберігається у IMemoryCache (або будь‑якому IDistributedCache, який ви налаштуєте) і автоматично закінчує термін дії після періоду бездіяльності (за замовчуванням 60 хвилин). Коли ви завершили, можете викликати CloseDocument, щоб раніше звільнити запис у кеші.
Реєстрація безстанового переглядача
Оскільки у Viewer немає змінного стану, зареєструйте його один раз під час запуску:
builder.Services.AddDoconut(); // реєструє Viewer та необхідне middleware
builder.Services.AddSession(); // необхідно для безпеки токену
builder.Services.AddDistributedMemoryCache(); // простий кеш для демонстрації
Виклик AddDoconut також підключає middleware, який обслуговує статичні ресурси переглядача. Після того, як сервіси налаштовані, ви можете запитувати Viewer у будь‑якому сигнатурі кінцевої точки.
Мінімальна кінцева точка відкриття документа (приклад net‑8)
Наступний код — точний фрагмент з офіційної документації і працює «з коробки» у проєкті .NET 8 minimal‑API:
app.MapPost("/api/open", async (string fileName, Viewer viewer) =>
{
var token = await viewer.OpenDocumentAsync($"files/{fileName}");
return Results.Content(token, "text/plain");
});
Що робить код
- Приймає ім’я файлу – клієнт повідомляє серверу, який файл під
wwwroot/filesвідкрити. - Викликає
OpenDocumentAsync– безстановийViewerстворює нову сесію, зберігає її в кеші та повертає непрозорий токен. - Повертає токен як простий текст – клієнт отримує лише токен; сервер ніколи не надсилає байти документа у цій відповіді.
Оскільки Viewer не містить даних документа, кінцева точка не потребує блоків using, викликів Dispose або фабрик на запит. Токен — єдина облікова дані, яку клієнт коли‑небудь надсилатиме назад до віджету переглядача (objViewer.View(token) на фронтенді).
Використання токену на стороні клієнта
Після того, як токен повернуто, фронтенд‑віджет викликає objViewer.View(token). Потім віджет включає той самий токен у кожен наступний запит за зображеннями сторінок, пошуком або діями анотації. Сервер перевіряє токен проти сесії, яка спочатку відкрила документ. Якщо токен подано з іншої браузерної сесії, переглядач повертає помилку авторизації, що є запланованою поведінкою безпеки.
Раннє закриття сесії (необов’язково)
Якщо ваш робочий процес знає, що документ більше ніколи не буде доступний, ви можете звільнити запис у кеші, викликавши CloseDocument на Viewer. Це видаляє сесію з кешу і запобігає роботі тайм‑ауту, який підтримує її живою.
Підсумок безстанового потоку
| Крок | Що відбувається | Де зберігається стан |
|---|---|---|
| Інжекція Переглядача | Один екземпляр Viewer створюється під час запуску. | У контейнері DI (одиночка). |
| OpenDocumentAsync | Перевірка ліцензії → створена сесія → повернуто токен. | Сесія зберігається у IMemoryCache (або розподіленому кеші). |
| Клієнт рендерить | Віджет надсилає токен у кожному запиті. | Токен — єдині дані на документ, які тримає клієнт. |
| Закінчення сесії / CloseDocument | Запис у кеші видаляється після тайм‑ауту або явного закриття. | Немає залишкових ресурсів у сервісі Переглядача. |
Оскільки сам сервіс ніколи не зберігає дані документа, ви можете безпечно масштабувати ваш веб‑ферму, замінювати вузли або перезапускати застосунок без втрати будь‑якого користувацького стану — лише токен стає недійсним, змушуючи клієнт повторно відкрити документ.
Розгортання безстанового переглядача у вашому застосунку
- Додайте
AddDoconut,AddSessionта провайдер кешу доProgram.cs. - Вставте фрагмент відкритої кінцевої точки у вашу конфігурацію minimal‑API.
- Передайте повернутий токен до
objViewer.View(token)на фронтенді.
Тепер у вас є повністю безстановий, готовий до продакшну API відкриття документів, який використовує дизайн Doconut’s Viewer.