نحوه کار Viewer

دورهٔ درخواست سند

Doconut اسناد را به‌صورت تصاویر صفحه‌بندی‌شده که از طریق میدل‌ویر ASP.NET Core سرو می‌شوند، رندر می‌کند. درک چرخهٔ حیات — باز کردن، توکن، درخواست‌های صفحه، بستن — تقریباً تمام رفتارهایی را که مشاهده می‌کنید، از جمله پیام‌های خطا، توضیح می‌دهد.

سه بخش متحرک

  • Viewer — سرویس عمومی که تزریق می‌کنید. اسناد را باز می‌کند و توکن‌های جلسه را برمی‌گرداند.
  • جلسهٔ سند — شیء سمت سرور که سند بارگذاری‌شده را نگه می‌دارد، با کلید توکن در IMemoryCache.
  • میان‌افزار Doconut — توسط UseDoconut() اضافه شده؛ به هر درخواست که ویجت مرورگر می‌فرستد (pages، thumbnails، search، annotations، …) پاسخ می‌دهد و همیشه توسط توکن احراز می‌شود.

Viewer بدون حالت — به‌صورت پیش‌فرض

Viewer مهر و موم شده است، هیچ وضعیت سندی برای هر درخواست را نگه نمی‌دارد و عمداً پیاده‌سازی 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 پرتاب می‌کند، با دلیل رد به‌عنوان پیام — باز کردن هرگز به‌صورت خاموش برای یک مجوز نامعتبر (در مقابل غیاب) کاهش نمی‌یابد. یک مجوز موقت یا اشتراکی که تاریخ‌اش منقضی شده است استثنا است: آن پرتاب نمی‌کند — به یک واترمارک کاهش می‌یابد.
  2. ایجاد جلسه. کارخانهٔ ویور فرمت مناسب برای پسوند فایل را انتخاب می‌کند و سند را بارگذاری می‌نماید (به «Rendering Pipeline» مراجعه کنید). جلسه در IMemoryCache تحت یک توکن GUID جدید با انقضای لغزان ذخیره می‌شود — DocOptions.TimeOut دقیقه، پیش‌فرض ۶۰. هر درخواست صفحه ساعت را ریست می‌کند.
  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کپی متن، پیوندها، و اطلاعات فرمت
?token=…&metaمتادیتای فنی DICOM؛ برای یک جلسه DICOM در .NET 6، 501 را برمی‌گرداند
?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 را تزریق کرد و به‌صورت آزاد به اشتراک گذاشت؛ جلسات تمام وضعیت را حمل می‌کنند.

آیا این صفحه مفید بود؟