كيف يعمل 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. إنشاء الجلسة. تختار مصنع العارض العارض المناسب لتنسيق الملف بناءً على امتداد الملف وتحمّل المستند (انظر خط أنابيب العرض). تُخزن الجلسة في 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 يمكن حقنه ومشاركته بحرية؛ الجلسات تحمل كل الحالة.

هل كانت هذه الصفحة مفيدة؟