كيف يعمل العارض

دورة حياة طلب المستند

Doconut يعرض المستندات كصور مقسمة إلى صفحات، يتم تقديمها عبر معالج HTTP يسجّله ملف Web.config الخاص بك. فهم دورة الحياة — الفتح، الرمز، طلبات الصفحات، الإغلاق — يوضح تقريبًا كل سلوك ستلاحظه، بما في ذلك رسائل الأخطاء.

الأجزاء المتحركة

  • Viewer — الخدمة العامة التي تستخرجها من DoconutHost.Services. تقوم بفتح المستندات وتعيد رموز الجلسة.
  • جلسة المستند — كائن على جانب الخادم يحتفظ بالمستند المحمَّل، يُخزَّن في الذاكرة تحت رمزه.
  • DocImage.axd — Doconut.DocImageHandler المعلن في Web.config. يجيب على كل طلب يقدمه عنصر المتصفح (صفحات، صور مصغرة، بحث، تعليقات توضيحية، …)، دائمًا يُحدَّد بالرمز.
  • /doconut-res/* — Doconut.DoconutResourceModule، الذي يقدم السكريبتات، الأنماط، والأيقونات الخاصة بالعنصر.

Viewer بلا حالة — حسب التصميم

Viewer لا يحتفظ بحالة مستند لكل طلب ولا ينفّذ IDisposable. الجلسات تعيش بشكل مستقل عنه وتُنظَّف عند الانتهاء أو عند استدعاء صريح لـ CloseDocument(token). لا يحتوي System.Web على حقن مُنشئ، لذا استخرجها حيث تحتاجها — عادةً في إجراء المتحكم:

csharp
// POST /ViewerApi/Open?fileName=Sample.pdf
[HttpPost]
public async Task<ActionResult> Open(string fileName)
{
    var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
    var path   = Server.MapPath("~/files/" + Path.GetFileName(fileName));

    var token = await viewer.OpenDocumentAsync(path);
    return Content(token, "text/plain");
}

ما يحدث داخل OpenDocumentAsync

  1. بوابة الترخيص. ترخيص مرفوض (مُعدَّل، مدرج على القائمة السوداء، أو بناء خارج نافذة تحديث الترخيص) يرمي LicenseException فورًا، مع السبب كرسالة. الفتح لا يتدهور صامتًا عند ترخيص غير صالح؛ الترخيص المفقود يضيف علامة مائية فقط.
  2. إنشاء الجلسة. مصنع العارض يختار عارض الصيغة بناءً على امتداد الملف ويحمل المستند (انظر خط أنابيب العرض). تُخزَّن الجلسة في الذاكرة تحت رمز عشوائي جديد مع انتهاء متزلج لمدة DocOptions.TimeOut دقيقة (الافتراضي 60). كل طلب صفحة يعيد ضبط المؤقت.
  3. منح الوصول. عندما يكون UnsafeMode = false (الإعداد الافتراضي)، يُربط الرمز بـ جلسة ASP.NET للطلب الذي فتحه: يُكتب إدخال secure-{token} في تلك الجلسة. لذلك يجب أن يتم الفتح في طلب يحتوي على حالة الجلسة — انظر الجلسات والأمان.
  4. إرجاع الرمز. هو المعرف الوحيد الذي يحتاجه المتصفح لكل ما يلي.

تقبل التحميلات غير المتزامنة مسار ملف، مسار ملف مع تكوين خاص بالصيغ (PdfConfig، WordConfig، …)، أو Stream مع FileInfo يحدِّد الصيغة بامتداده. بالنسبة لشفرة خلفية Web Forms التي لا تستخدم الصفحات غير المتزامنة، يقدم OpenDocument نفس المدخلات الثلاثة بشكل متزامن (مسار، تدفق مع اسم ملف، أو مصفوفة بايت مع اسم ملف).

كيف يحصل الودجت على الصفحات

الودجت يستدعي DocImage.axd مع الرمز في سلسلة الاستعلام. ما يفعله المعالج يعتمد على الطلب:

الاستعلامالغرض
?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إجراءات الصفحة وإغلاق صريح (POST)
?token=…&AnnSave=… / &AnnLoadحفظ وتحميل التعليقات التوضيحية

يُفحص كل طلب أولًا:

  • بدون رمز → 404، أو شريط نسخة عندما يكون ShowDoconutInfo = true.
  • الرمز غير مُمنوح لهذه جلسة ASP.NET → صورة خطأ تُظهر النص You Are Not Authorized To View This Page..
  • رمز غير معروف أو منتهي → صورة خطأ تُظهر النص Document session not found. Please re-open document..

صور الخطأ هي PNG عادية تُرسل بحالة 200، بحيث يمكن للودجت عرضها حيث ستكون الصفحة. فحص المراقبة الذي يتحقق فقط من رمز الحالة سيُبلغ عنها كصفحات مُقدمة؛ الصفحة الفعلية تكون بحجم عشرات إلى مئات الكيلوبايت، بينما صورة الخطأ حوالي 2 كيلوبايت.

إغلاق مستند

csharp
viewer.CloseDocument(token);

CloseDocument يزيل الجلسة (مُحرِّر محرك المستند وذاكرته فورًا)، يزيل إدخال secure-{token} من جلسة ASP.NET للطلب الحالي، ويُبطل الرمز. هذا اختياري — انتهاء الانزلاق يقوم بنفس التنظيف — لكن للمستندات الكبيرة يحرّر الذاكرة فور انتهاء المستخدم. من المتصفح، objViewer.Close(true) يرسل طلب الإغلاق المكافئ إلى DocImage.axd.

الخلاصات

  • مستند مفتوح واحد = جلسة واحدة = رمز واحد، يُمنح لجلسة ASP.NET التي فتحته.
  • الرمز ينتهي في نافذة متزلجة؛ عارض يبقى غير نشط بعد DocOptions.TimeOut يحتاج إلى إعادة فتح.
  • يمكن استخراج Viewer ومشاركتها بحرية؛ الجلسات تحمل كل الحالة.

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