איך הצופה עובד

מחזור חיי בקשת המסמך

Doconut מציג מסמכים כתמונות ממודרות, המוגשות על‑ידי מטפל HTTP שה‑Web.config שלך רושם. הבנת מחזור החיים — פתיחה, אסימון, בקשות דף, סגירה — מסבירה כמעט כל התנהגות שתתבונן בה, כולל הודעות השגיאה.

החלקים הנעים

  • Viewer — השירות הציבורי שאתה מקבל מ‑DoconutHost.Services. הוא פותח מסמכים ומחזיר אסימוני סשן.
  • סשן המסמך — אובייקט צד שרת המחזיק את המסמך הטעון, נשמר בזיכרון תחת האסימון שלו.
  • DocImage.axd — ה‑Doconut.DocImageHandler המוצהר ב‑Web.config. הוא משיב לכל בקשה שהווידג'ט של הדפדפן עושה (דפים, תמונות ממוזערות, חיפוש, anotations, …), תמיד מזוהה באמצעות האסימון.
  • /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 בחופשיות; הסשנים נושאים את כל המצב.

האם דף זה היה מועיל?